diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT index f2b8477a27c6..8bc1c5d69f80 100644 --- a/CODE_OWNERS.TXT +++ b/CODE_OWNERS.TXT @@ -65,7 +65,7 @@ E: qcolombet@apple.com D: Loop Strength Reduction, Register allocators N: Simon Dardis -E: simon.dardis@imgtec.com +E: simon.dardis@mips.com D: MIPS Backend (lib/Target/Mips/*) N: Duncan P. N. Exon Smith diff --git a/RELEASE_TESTERS.TXT b/RELEASE_TESTERS.TXT index 9a01c725fb51..0505a4aecb9d 100644 --- a/RELEASE_TESTERS.TXT +++ b/RELEASE_TESTERS.TXT @@ -47,6 +47,6 @@ T: ARM, AArch64 O: Linux N: Simon Dardis -E: simon.dardis@imgtec.com +E: simon.dardis@mips.com T: MIPS O: Linux diff --git a/lib/CodeGen/CountingFunctionInserter.cpp b/lib/CodeGen/CountingFunctionInserter.cpp index 7f7350f5fb5c..15af09807ba6 100644 --- a/lib/CodeGen/CountingFunctionInserter.cpp +++ b/lib/CodeGen/CountingFunctionInserter.cpp @@ -27,13 +27,13 @@ namespace { CountingFunctionInserter() : FunctionPass(ID) { initializeCountingFunctionInserterPass(*PassRegistry::getPassRegistry()); } - + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addPreserved(); } bool runOnFunction(Function &F) override { - std::string CountingFunctionName = + StringRef CountingFunctionName = F.getFnAttribute("counting-function").getValueAsString(); if (CountingFunctionName.empty()) return false; @@ -46,17 +46,13 @@ namespace { return true; } }; - + char CountingFunctionInserter::ID = 0; } -INITIALIZE_PASS(CountingFunctionInserter, "cfinserter", +INITIALIZE_PASS(CountingFunctionInserter, "cfinserter", "Inserts calls to mcount-like functions", false, false) -//===----------------------------------------------------------------------===// -// -// CountingFunctionInserter - Give any unnamed non-void instructions "tmp" names. -// FunctionPass *llvm::createCountingFunctionInserterPass() { return new CountingFunctionInserter(); } diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 9f49e67ced4c..1f06d4065b39 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3297,7 +3297,8 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, } } -std::string AArch64MnemonicSpellCheck(StringRef S, uint64_t FBS); +static std::string AArch64MnemonicSpellCheck(StringRef S, uint64_t FBS, + unsigned VariantID = 0); bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, OperandVector &Operands) { @@ -4255,6 +4256,7 @@ extern "C" void LLVMInitializeAArch64AsmParser() { #define GET_REGISTER_MATCHER #define GET_SUBTARGET_FEATURE_NAME #define GET_MATCHER_IMPLEMENTATION +#define GET_MNEMONIC_SPELL_CHECKER #include "AArch64GenAsmMatcher.inc" // Define this matcher function after the auto-generated include so we diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 6a3dba75d969..5ad7f72f6dab 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -9040,7 +9040,8 @@ unsigned ARMAsmParser::MatchInstruction(OperandVector &Operands, MCInst &Inst, return PlainMatchResult; } -std::string ARMMnemonicSpellCheck(StringRef S, uint64_t FBS); +static std::string ARMMnemonicSpellCheck(StringRef S, uint64_t FBS, + unsigned VariantID = 0); static const char *getSubtargetFeatureName(uint64_t Val); bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, @@ -10120,6 +10121,7 @@ extern "C" void LLVMInitializeARMAsmParser() { #define GET_REGISTER_MATCHER #define GET_SUBTARGET_FEATURE_NAME #define GET_MATCHER_IMPLEMENTATION +#define GET_MNEMONIC_SPELL_CHECKER #include "ARMGenAsmMatcher.inc" // Some diagnostics need to vary with subtarget features, so they are handled diff --git a/lib/Target/Mips/MicroMipsInstrFPU.td b/lib/Target/Mips/MicroMipsInstrFPU.td index ee40a79ccfdb..49025cc1570a 100644 --- a/lib/Target/Mips/MicroMipsInstrFPU.td +++ b/lib/Target/Mips/MicroMipsInstrFPU.td @@ -95,8 +95,16 @@ def CVT_L_S_MM : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, II_CVT>, def CVT_L_D64_MM : MMRel, ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, II_CVT>, ROUND_W_FM_MM<1, 0x4>, ISA_MICROMIPS, FGR_64; -def FABS_S_MM : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>, - ABS_FM_MM<0, 0xd>, ISA_MICROMIPS; +} + +let DecoderNamespace = "MicroMips" in { + def FABS_S_MM : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>, + ABS_FM_MM<0, 0xd>, ISA_MICROMIPS; + def FABS_MM : MMRel, ABSS_FT<"abs.d", AFGR64Opnd, AFGR64Opnd, II_ABS, fabs>, + ABS_FM_MM<1, 0xd>, ISA_MICROMIPS, FGR_32; +} + +let isCodeGenOnly = 1 in { def FMOV_S_MM : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>, ABS_FM_MM<0, 0x1>, ISA_MICROMIPS; def FNEG_S_MM : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>, @@ -110,8 +118,6 @@ def CVT_S_D32_MM : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>, def CVT_S_W_MM : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, II_CVT>, ABS_FM_MM<1, 0x6d>, ISA_MICROMIPS; -def FABS_MM : MMRel, ABSS_FT<"abs.d", AFGR64Opnd, AFGR64Opnd, II_ABS, fabs>, - ABS_FM_MM<1, 0xd>, ISA_MICROMIPS, FGR_32; def FNEG_MM : MMRel, ABSS_FT<"neg.d", AFGR64Opnd, AFGR64Opnd, II_NEG, fneg>, ABS_FM_MM<1, 0x2d>, ISA_MICROMIPS, FGR_32; diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 89b9e5e7a81a..c81739115373 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -448,11 +448,14 @@ let isPseudo = 1, isCodeGenOnly = 1 in { def PseudoCVT_D64_L : ABSS_FT<"", FGR64Opnd, GPR64Opnd, II_CVT>; } -def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>, - ABSS_FM<0x5, 16>; +let AdditionalPredicates = [NotInMicroMips] in { + def FABS_S : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>, + ABSS_FM<0x5, 16>; + defm FABS : ABSS_M<"abs.d", II_ABS, fabs>, ABSS_FM<0x5, 17>; +} + def FNEG_S : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>, ABSS_FM<0x7, 16>; -defm FABS : ABSS_M<"abs.d", II_ABS, fabs>, ABSS_FM<0x5, 17>; defm FNEG : ABSS_M<"neg.d", II_NEG, fneg>, ABSS_FM<0x7, 17>; def FSQRT_S : MMRel, StdMMR6Rel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index f1526eb2e219..661ead4803be 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -157,24 +157,23 @@ unsigned MipsInstrInfo::removeBranch(MachineBasicBlock &MBB, assert(!BytesRemoved && "code size not handled"); MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); - unsigned removed; - - // Skip all the debug instructions. - while (I != REnd && I->isDebugValue()) - ++I; - - if (I == REnd) - return 0; - - MachineBasicBlock::iterator FirstBr = ++I.getReverse(); + unsigned removed = 0; // Up to 2 branches are removed. // Note that indirect branches are not removed. - for (removed = 0; I != REnd && removed < 2; ++I, ++removed) + while (I != REnd && removed < 2) { + // Skip past debug instructions. + if (I->isDebugValue()) { + ++I; + continue; + } if (!getAnalyzableBrOpc(I->getOpcode())) break; - - MBB.erase((--I).getReverse(), FirstBr); + // Remove the branch. + I->eraseFromParent(); + I = MBB.rbegin(); + ++removed; + } return removed; } diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index d12610d1eed3..70920294aea2 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1715,38 +1715,47 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, else if (MI->getParent() != CmpInstr.getParent()) return false; else if (Value != 0) { - // The record-form instructions set CR bit based on signed comparison against 0. - // We try to convert a compare against 1 or -1 into a compare against 0. - bool Success = false; - if (!equalityOnly && MRI->hasOneUse(CRReg)) { - MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg); - if (UseMI->getOpcode() == PPC::BCC) { - PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm(); - unsigned PredCond = PPC::getPredicateCondition(Pred); - unsigned PredHint = PPC::getPredicateHint(Pred); - int16_t Immed = (int16_t)Value; - - // When modyfing the condition in the predicate, we propagate hint bits - // from the original predicate to the new one. - if (Immed == -1 && PredCond == PPC::PRED_GT) { - // We convert "greater than -1" into "greater than or equal to 0", - // since we are assuming signed comparison by !equalityOnly - PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)), - PPC::getPredicate(PPC::PRED_GE, PredHint))); - Success = true; - } - else if (Immed == 1 && PredCond == PPC::PRED_LT) { - // We convert "less than 1" into "less than or equal to 0". - PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)), - PPC::getPredicate(PPC::PRED_LE, PredHint))); - Success = true; - } - } - } + // The record-form instructions set CR bit based on signed comparison + // against 0. We try to convert a compare against 1 or -1 into a compare + // against 0 to exploit record-form instructions. For example, we change + // the condition "greater than -1" into "greater than or equal to 0" + // and "less than 1" into "less than or equal to 0". + + // Since we optimize comparison based on a specific branch condition, + // we don't optimize if condition code is used by more than once. + if (equalityOnly || !MRI->hasOneUse(CRReg)) + return false; + + MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg); + if (UseMI->getOpcode() != PPC::BCC) + return false; - // PPC does not have a record-form SUBri. - if (!Success) + PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm(); + PPC::Predicate NewPred = Pred; + unsigned PredCond = PPC::getPredicateCondition(Pred); + unsigned PredHint = PPC::getPredicateHint(Pred); + int16_t Immed = (int16_t)Value; + + // When modyfing the condition in the predicate, we propagate hint bits + // from the original predicate to the new one. + if (Immed == -1 && PredCond == PPC::PRED_GT) + // We convert "greater than -1" into "greater than or equal to 0", + // since we are assuming signed comparison by !equalityOnly + NewPred = PPC::getPredicate(PPC::PRED_GE, PredHint); + else if (Immed == -1 && PredCond == PPC::PRED_LE) + // We convert "less than or equal to -1" into "less than 0". + NewPred = PPC::getPredicate(PPC::PRED_LT, PredHint); + else if (Immed == 1 && PredCond == PPC::PRED_LT) + // We convert "less than 1" into "less than or equal to 0". + NewPred = PPC::getPredicate(PPC::PRED_LE, PredHint); + else if (Immed == 1 && PredCond == PPC::PRED_GE) + // We convert "greater than or equal to 1" into "greater than 0". + NewPred = PPC::getPredicate(PPC::PRED_GT, PredHint); + else return false; + + PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)), + NewPred)); } // Search for Sub. diff --git a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index 1cc01af509c3..bde067d6c129 100644 --- a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -543,6 +543,7 @@ class SystemZAsmParser : public MCTargetAsmParser { #define GET_REGISTER_MATCHER #define GET_SUBTARGET_FEATURE_NAME #define GET_MATCHER_IMPLEMENTATION +#define GET_MNEMONIC_SPELL_CHECKER #include "SystemZGenAsmMatcher.inc" // Used for the .insn directives; contains information needed to parse the @@ -1168,7 +1169,8 @@ bool SystemZAsmParser::parseOperand(OperandVector &Operands, return false; } -std::string SystemZMnemonicSpellCheck(StringRef S, uint64_t FBS); +static std::string SystemZMnemonicSpellCheck(StringRef S, uint64_t FBS, + unsigned VariantID = 0); bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 0d211c415de1..896c50a93287 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -909,7 +909,7 @@ class X86AsmParser : public MCTargetAsmParser { MCSubtargetInfo &STI = copySTI(); FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit}); FeatureBitset OldMode = STI.getFeatureBits() & AllModes; - unsigned FB = ComputeAvailableFeatures( + uint64_t FB = ComputeAvailableFeatures( STI.ToggleFeature(OldMode.flip(mode))); setAvailableFeatures(FB); diff --git a/test/CodeGen/Mips/pr35071.ll b/test/CodeGen/Mips/pr35071.ll new file mode 100644 index 000000000000..ae60f69a0808 --- /dev/null +++ b/test/CodeGen/Mips/pr35071.ll @@ -0,0 +1,73 @@ +; RUN: llc -mtriple mips64-unknown-freebsd12.0 -relocation-model pic -mcpu=mips4 -target-abi n64 -O2 -o - %s + +; Test that the long branch pass does not crash due to the control flow +; optimizer producing malformed basic block operands due to the backend +; failing to handle debug information around branch instructions. + +define void @f() !dbg !5 { +entry: + %cmp = icmp eq i32 undef, 0, !dbg !16 + %conv = zext i1 %cmp to i32, !dbg !16 + tail call void @llvm.dbg.value(metadata i32 %conv, metadata !11, metadata !DIExpression()), !dbg !17 + %tobool = icmp eq i32 undef, 0, !dbg !18 + br i1 %tobool, label %if.end, label %cleanup7.critedge, !dbg !21 + +if.end: ; preds = %entry + %call6 = call i32 bitcast (i32 (...)* @j to i32 (i32)*)(i32 signext %conv) +#4, !dbg !22 + br label %cleanup7, !dbg !23 + +cleanup7.critedge: ; preds = %entry + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull undef) #4, !dbg !24 + br label %cleanup7 + +cleanup7: ; preds = %cleanup7.critedge, + ret void +} + +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 + +declare i32 @j(...) + +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 +attributes #1 = { argmemonly nounwind } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang +version 6.0.0", isOptimized: true, runtimeVersion: +0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: +"/tmp//", directory: +"/tmp/") +!2 = !{} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 7, !"PIC Level", i32 2} +!5 = distinct !DISubprogram(name: "f", scope: !6, file: !6, line: 8, type: !7, +isLocal: false, isDefinition: true, scopeLine: 8, isOptimized: true, unit: !0, +variables: !10) +!6 = !DIFile(filename: +"/tmp/test.c", +directory: "/tmp") +!7 = !DISubroutineType(types: !8) +!8 = !{!9} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{!11, !12, !14} +!11 = !DILocalVariable(name: "e", scope: !5, file: !6, line: 9, type: !9) +!12 = !DILocalVariable(name: "g", scope: !13, file: !6, line: 11, type: !9) +!13 = distinct !DILexicalBlock(scope: !5, file: !6, line: 10, column: 3) +!14 = !DILocalVariable(name: "d", scope: !13, file: !6, line: 12, type: !15) +!15 = !DIDerivedType(tag: DW_TAG_typedef, name: "a", file: !6, line: 2, +baseType: !9) +!16 = !DILocation(line: 9, column: 15, scope: !5) +!17 = !DILocation(line: 9, column: 7, scope: !5) +!18 = !DILocation(line: 12, column: 5, scope: !19) +!19 = distinct !DILexicalBlock(scope: !20, file: !6, line: 12, column: 5) +!20 = distinct !DILexicalBlock(scope: !5, file: !6, line: 10, column: 3) +!21 = !DILocation(line: 12, column: 5, scope: !20) +!22 = !DILocation(line: 16, column: 3, scope: !5) +!23 = !DILocation(line: 17, column: 1, scope: !5) +!24 = !DILocation(line: 15, column: 3, scope: !5) diff --git a/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll b/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll index 43d4add243d2..5176cdcb6007 100644 --- a/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll +++ b/test/CodeGen/PowerPC/opt-cmp-inst-cr0-live.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs -print-before=peephole-opt -print-after=peephole-opt -mtriple=powerpc64-unknown-linux-gnu -o /dev/null 2>&1 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -print-before=peephole-opt -print-after=peephole-opt -mtriple=powerpc64le-unknown-linux-gnu -o /dev/null 2>&1 < %s | FileCheck %s ; CHECK-LABEL: fn1 define signext i32 @fn1(i32 %baz) { @@ -99,3 +100,38 @@ foo: bar: ret i32 0 } + +; This test confirms record-form instructions are emitted for comparison +; against a non-zero value. + +; CHECK-LABEL: fn6 +define i8* @fn6(i8* readonly %p) { +; CHECK: LBZU +; CHECK: EXTSBo +; CHECK-NOT: CMP +; CHECK: BCC +; CHECK: LBZU +; CHECK: EXTSBo +; CHECK-NOT: CMP +; CHECK: BCC + +entry: + %incdec.ptr = getelementptr inbounds i8, i8* %p, i64 -1 + %0 = load i8, i8* %incdec.ptr + %cmp = icmp sgt i8 %0, -1 + br i1 %cmp, label %out, label %if.end + +if.end: + %incdec.ptr2 = getelementptr inbounds i8, i8* %p, i64 -2 + %1 = load i8, i8* %incdec.ptr2 + %cmp4 = icmp sgt i8 %1, -1 + br i1 %cmp4, label %out, label %cleanup + +out: + %p.addr.0 = phi i8* [ %incdec.ptr, %entry ], [ %incdec.ptr2, %if.end ] + br label %cleanup + +cleanup: + %retval.0 = phi i8* [ %p.addr.0, %out ], [ null, %if.end ] + ret i8* %retval.0 +} diff --git a/test/MC/Disassembler/Mips/micromips32r3/valid-el.txt b/test/MC/Disassembler/Mips/micromips32r3/valid-el.txt index 3a1799dc5984..dc76f48a95a5 100644 --- a/test/MC/Disassembler/Mips/micromips32r3/valid-el.txt +++ b/test/MC/Disassembler/Mips/micromips32r3/valid-el.txt @@ -49,6 +49,8 @@ 0x88 0x46 # CHECK: break16 8 0xce 0x46 # CHECK: sdbbp16 14 0x34 0x84 # CHECK: movep $5, $6, $2, $3 +0x40 0x54 0x7b 0x03 # CHECK: abs.s $f2, $f0 +0x40 0x54 0x7b 0x23 # CHECK: abs.d $f2, $f0 0xe6 0x00 0x10 0x49 # CHECK: add $9, $6, $7 0x26 0x11 0x67 0x45 # CHECK: addi $9, $6, 17767 0x26 0x31 0x67 0xc5 # CHECK: addiu $9, $6, -15001 diff --git a/test/MC/Disassembler/Mips/micromips32r3/valid.txt b/test/MC/Disassembler/Mips/micromips32r3/valid.txt index 675ef9e4e8b9..38d6897e1c4f 100644 --- a/test/MC/Disassembler/Mips/micromips32r3/valid.txt +++ b/test/MC/Disassembler/Mips/micromips32r3/valid.txt @@ -49,6 +49,8 @@ 0x46 0x88 # CHECK: break16 8 0x46 0xce # CHECK: sdbbp16 14 0x84 0x34 # CHECK: movep $5, $6, $2, $3 +0x54 0x40 0x03 0x7b # CHECK: abs.s $f2, $f0 +0x54 0x40 0x23 0x7b # CHECK: abs.d $f2, $f0 0x00 0xe6 0x49 0x10 # CHECK: add $9, $6, $7 0x11 0x26 0x45 0x67 # CHECK: addi $9, $6, 17767 0x31 0x26 0xc5 0x67 # CHECK: addiu $9, $6, -15001 diff --git a/test/MC/Disassembler/X86/x86-64.txt b/test/MC/Disassembler/X86/x86-64.txt index 05ea82d13023..dbc49eb3f689 100644 --- a/test/MC/Disassembler/X86/x86-64.txt +++ b/test/MC/Disassembler/X86/x86-64.txt @@ -479,6 +479,14 @@ # CHECK: nopq %rax 0x48 0x0f 0x1f 0xC0 +# TODO: wrong dissassembler with 0x67 prefix: expected popq +# CHECK: popw %r14 +0x67 0x49 0x5e + +# TODO: wrong dissassembler with 0x67 prefix: expected pushq +# CHECK: pushw %r14 +0x67 0x49 0x56 + # CHECK: xchgw %di, %ax 0x66 0x3e 0x97 diff --git a/test/MC/Mips/micromips/valid.s b/test/MC/Mips/micromips/valid.s index 94132dafe06c..47266c9da100 100644 --- a/test/MC/Mips/micromips/valid.s +++ b/test/MC/Mips/micromips/valid.s @@ -49,6 +49,10 @@ sdbbp16 14 # CHECK: sdbbp16 14 # encoding: [0x46,0xce] lw $3, 32($sp) # CHECK: lw $3, 32($sp) # encoding: [0x48,0x68] sw $4, 124($sp) # CHECK: sw $4, 124($sp) # encoding: [0xc8,0x9f] lw $3, 32($gp) # CHECK: lw $3, 32($gp) # encoding: [0x65,0x88] +abs.s $f0, $f2 # CHECK: abs.s $f0, $f2 # encoding: [0x54,0x02,0x03,0x7b] + # CHECK-NEXT: # Candidates;\n"; - OS << " StringRef Prev = \"\";\n"; - OS << " auto End = std::end(MatchTable0);\n"; - OS << "\n"; - OS << " for (auto I = std::begin(MatchTable0); I < End; I++) {\n"; + OS << " StringRef Prev = \"\";\n\n"; + + OS << " // Find the appropriate table for this asm variant.\n"; + OS << " const MatchEntry *Start, *End;\n"; + OS << " switch (VariantID) {\n"; + OS << " default: llvm_unreachable(\"invalid variant!\");\n"; + for (unsigned VC = 0; VC != VariantCount; ++VC) { + Record *AsmVariant = Target.getAsmParserVariant(VC); + int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); + OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC + << "); End = std::end(MatchTable" << VC << "); break;\n"; + } + OS << " }\n\n"; + OS << " for (auto I = Start; I < End; I++) {\n"; OS << " // Ignore unsupported instructions.\n"; OS << " if ((FBS & I->RequiredFeatures) != I->RequiredFeatures)\n"; OS << " continue;\n"; @@ -3159,8 +3170,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "};\n\n"; } - emitMnemonicSpellChecker(OS, Target, VariantCount); - OS << "#include \"llvm/Support/Debug.h\"\n"; OS << "#include \"llvm/Support/Format.h\"\n\n"; @@ -3576,6 +3585,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { MaxMnemonicIndex, HasMnemonicFirst); OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n"; + + OS << "\n#ifdef GET_MNEMONIC_SPELL_CHECKER\n"; + OS << "#undef GET_MNEMONIC_SPELL_CHECKER\n\n"; + + emitMnemonicSpellChecker(OS, Target, VariantCount); + + OS << "#endif // GET_MNEMONIC_SPELL_CHECKER\n\n"; } namespace llvm {