Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -203,6 +203,11 @@ uint64_t Address, const void *Decoder); +static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset, uint64_t Address, @@ -1833,6 +1838,16 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + int32_t BranchOffset = SignExtend32<21>(Offset) << 1; + + Inst.addOperand(MCOperand::createImm(BranchOffset)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeBranchTarget26(MCInst &Inst, unsigned Offset, uint64_t Address, Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -130,6 +130,13 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + // getBranchTarget21OpValueMM - Return binary encoding of the branch + // offset operand for microMIPS. If the machine operand requires + // relocation,record the relocation and return zero. + unsigned getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getBranchTarget26OpValue - Return binary encoding of the branch // offset operand. If the machine operand requires relocation, // record the relocation and return zero. Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -327,6 +327,26 @@ return 0; } +/// getBranchTarget21OpValueMM - Return binary encoding of the branch +/// target operand for microMIPS. If the machine operand requires +/// relocation, record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, +SmallVectorImpl &Fixups, +const MCSubtargetInfo &STI) const { + + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTarget21OpValueMM expects only expressions or immediates"); + + // TODO: Push fixup. + return 0; +} + /// getBranchTarget26OpValue - Return binary encoding of the branch /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -858,3 +858,14 @@ let Inst{10-9} = fmt; let Inst{8-0} = funct; } + +class CMP_BRANCH_OFF21_FM_MMR6 funct> : MipsR6Inst { + bits<5> rs; + bits<21> offset; + + bits<32> Inst; + + let Inst{31-26} = funct; + let Inst{25-21} = rs; + let Inst{20-0} = offset; +} Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -11,6 +11,13 @@ // //===----------------------------------------------------------------------===// +def brtarget21_mm : Operand { + let EncoderMethod = "getBranchTarget21OpValueMM"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTarget21MM"; + let ParserMatchClass = MipsJumpTargetAsmOperand; +} + def brtarget26_mm : Operand { let EncoderMethod = "getBranchTarget26OpValueMM"; let OperandType = "OPERAND_PCREL"; @@ -40,6 +47,8 @@ class BNEZC16_MMR6_ENC : BEQZC_BNEZC_FM_MM16R6<0x2b>; class BITSWAP_MMR6_ENC : POOL32A_BITSWAP_FM_MMR6<0b101100>; class BRK_MMR6_ENC : BREAK_MMR6_ENC<"break">; +class BEQZC_MMR6_ENC : CMP_BRANCH_OFF21_FM_MMR6<"beqzc", 0b100000>; +class BNEZC_MMR6_ENC : CMP_BRANCH_OFF21_FM_MMR6<"bnezc", 0b101000>; class BEQZALC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<0b011101>; class BNEZALC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<0b011111>; class BGTZALC_MMR6_ENC : CMP_BRANCH_1R_RT_OFF16_FM_MMR6<0b111000>; @@ -920,6 +929,13 @@ let mayStore = 1; } +class BEQZC_MMR6_DESC + : CMP_CBR_EQNE_Z_DESC_BASE<"beqzc", brtarget21_mm, GPR32Opnd>, + MMR6Arch<"beqzc">; +class BNEZC_MMR6_DESC + : CMP_CBR_EQNE_Z_DESC_BASE<"bnezc", brtarget21_mm, GPR32Opnd>, + MMR6Arch<"bnezc">; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -942,8 +958,12 @@ def BALC_MMR6 : R6MMR6Rel, BALC_MMR6_ENC, BALC_MMR6_DESC, ISA_MICROMIPS32R6; def BC_MMR6 : R6MMR6Rel, BC_MMR6_ENC, BC_MMR6_DESC, ISA_MICROMIPS32R6; def BC16_MMR6 : StdMMR6Rel, BC16_MMR6_DESC, BC16_MMR6_ENC, ISA_MICROMIPS32R6; +def BEQZC_MMR6 : R6MMR6Rel, BEQZC_MMR6_ENC, BEQZC_MMR6_DESC, + ISA_MICROMIPS32R6; def BEQZC16_MMR6 : StdMMR6Rel, BEQZC16_MMR6_DESC, BEQZC16_MMR6_ENC, ISA_MICROMIPS32R6; +def BNEZC_MMR6 : R6MMR6Rel, BNEZC_MMR6_ENC, BNEZC_MMR6_DESC, + ISA_MICROMIPS32R6; def BNEZC16_MMR6 : StdMMR6Rel, BNEZC16_MMR6_DESC, BNEZC16_MMR6_ENC, ISA_MICROMIPS32R6; def BITSWAP_MMR6 : R6MMR6Rel, BITSWAP_MMR6_ENC, BITSWAP_MMR6_DESC, Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -310,7 +310,8 @@ } class CMP_CBR_EQNE_Z_DESC_BASE : BRANCH_DESC_BASE { + RegisterOperand GPROpnd> + : BRANCH_DESC_BASE, MipsR6Arch { dag InOperandList = (ins GPROpnd:$rs, opnd:$offset); dag OutOperandList = (outs); string AsmString = !strconcat(instr_asm, "\t$rs, $offset"); @@ -667,7 +668,7 @@ def BC : R6MMR6Rel, BC_ENC, BC_DESC, ISA_MIPS32R6; def BEQC : BEQC_ENC, BEQC_DESC, ISA_MIPS32R6; def BEQZALC : R6MMR6Rel, BEQZALC_ENC, BEQZALC_DESC, ISA_MIPS32R6; -def BEQZC : BEQZC_ENC, BEQZC_DESC, ISA_MIPS32R6; +def BEQZC : R6MMR6Rel, BEQZC_ENC, BEQZC_DESC, ISA_MIPS32R6; def BGEC : BGEC_ENC, BGEC_DESC, ISA_MIPS32R6; def BGEUC : BGEUC_ENC, BGEUC_DESC, ISA_MIPS32R6; def BGEZALC : R6MMR6Rel, BGEZALC_ENC, BGEZALC_DESC, ISA_MIPS32R6; @@ -683,7 +684,7 @@ def BLTZC : BLTZC_ENC, BLTZC_DESC, ISA_MIPS32R6; def BNEC : BNEC_ENC, BNEC_DESC, ISA_MIPS32R6; def BNEZALC : R6MMR6Rel, BNEZALC_ENC, BNEZALC_DESC, ISA_MIPS32R6; -def BNEZC : BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6; +def BNEZC : R6MMR6Rel, BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6; def BNVC : BNVC_ENC, BNVC_DESC, ISA_MIPS32R6; def BOVC : BOVC_ENC, BOVC_DESC, ISA_MIPS32R6; def CACHE_R6 : R6MMR6Rel, CACHE_ENC, CACHE_DESC, ISA_MIPS32R6; Index: test/MC/Disassembler/Mips/micromips32r6/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -44,6 +44,8 @@ 0xe0 0x40 0x02 0x9a # CHECK: bgtzalc $2, 1332 0xe0 0x42 0x02 0x9a # CHECK: bltzalc $2, 1332 0xc0 0x40 0x02 0x9a # CHECK: blezalc $2, 1332 +0x80 0x60 0x00 0x20 # CHECK: beqzc $3, 64 +0xa0 0x60 0x00 0x20 # CHECK: bnezc $3, 64 0xb4 0x37 0x96 0xb8 # CHECK: balc 7286128 0x94 0x37 0x96 0xb8 # CHECK: bc 7286128 0x00 0x44 0x0b 0x3c # CHECK: bitswap $4, $2 Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -26,6 +26,8 @@ bgtzalc $2, 1332 # CHECK: bgtzalc $2, 1332 # encoding: [0xe0,0x40,0x02,0x9a] bltzalc $2, 1332 # CHECK: bltzalc $2, 1332 # encoding: [0xe0,0x42,0x02,0x9a] blezalc $2, 1332 # CHECK: blezalc $2, 1332 # encoding: [0xc0,0x40,0x02,0x9a] + beqzc $3, 64 # CHECK: beqzc $3, 64 # encoding: [0x80,0x60,0x00,0x20] + bnezc $3, 64 # CHECK: bnezc $3, 64 # encoding: [0xa0,0x60,0x00,0x20] balc 7286128 # CHECK: balc 7286128 # encoding: [0xb4,0x37,0x96,0xb8] b 132 # CHECK: bc16 132 # encoding: [0xcc,0x42] bc 7286128 # CHECK: bc 7286128 # encoding: [0x94,0x37,0x96,0xb8]