Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -205,6 +205,16 @@ uint64_t Address, const void *Decoder); +static DecodeStatus DecodeBranchTarget21(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + +static DecodeStatus DecodeBranchTarget26(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + // DecodeBranchTargetMM - Decode microMIPS branch offset, which is // shifted left by 1 bit. static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, @@ -853,6 +863,26 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeBranchTarget21(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + unsigned BranchOffset = Offset & 0x1fffff; + BranchOffset = SignExtend32<23>(BranchOffset << 2); + Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeBranchTarget26(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + unsigned BranchOffset = Offset & 0x3ffffff; + BranchOffset = SignExtend32<28>(BranchOffset << 2); + Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeBranchTargetMM(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 @@ -88,6 +88,20 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + // getBranchTarget21OpValue - Return binary encoding of the branch + // offset operand. If the machine operand requires relocation, + // record the relocation and return zero. + unsigned getBranchTarget21OpValue(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. + unsigned getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getMachineOpValue - Return binary encoding of operand. If the machin // operand requires relocation, record the relocation and return zero. unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -242,6 +242,46 @@ return 0; } +/// getBranchTarget21OpValue - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget21OpValue(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 4. + if (MO.isImm()) return MO.getImm() >> 2; + + assert(MO.isExpr() && + "getBranchTarget21OpValue expects only expressions or immediates"); + + // TODO: Push 21 PC fixup. + return 0; +} + +/// getBranchTarget26OpValue - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTarget26OpValue(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 4. + if (MO.isImm()) return MO.getImm() >> 2; + + assert(MO.isExpr() && + "getBranchTarget26OpValue expects only expressions or immediates"); + + // TODO: Push 26 PC fixup. + return 0; +} + /// getJumpTargetOpValue - Return binary encoding of the jump /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. Index: lib/Target/Mips/Mips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/Mips32r6InstrFormats.td +++ lib/Target/Mips/Mips32r6InstrFormats.td @@ -32,3 +32,46 @@ let Inst{5-0} = funct; } +class BRANCH_OFF26_FM funct> : MipsR6Inst { + bits<32> Inst; + bits<26> offset; + + let Inst{31-26} = funct; + let Inst{25-0} = offset; +} + +class CMP_BRANCH_OFF16_FM funct> : MipsR6Inst { + bits<5> rs; + bits<5> rt; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = funct; + let Inst{25-21} = rs; + let Inst{20-16} = rt; + let Inst{15-0} = offset; +} + +class CMP_BRANCH_RT_OFF16_FM funct> : MipsR6Inst { + bits<5> rt; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = funct; + let Inst{25-21} = 0b00000; + let Inst{20-16} = rt; + let Inst{15-0} = offset; +} + +class CMP_BRANCH_OFF21_FM 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/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -54,12 +54,40 @@ // Removed: teqi, tgei, tgeiu, tlti, tltiu, tnei // Rencoded: [ls][wd]c2 +def brtarget21 : Operand { + let EncoderMethod = "getBranchTarget21OpValue"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTarget21"; + let ParserMatchClass = MipsJumpTargetAsmOperand; +} + +def brtarget26 : Operand { + let EncoderMethod = "getBranchTarget26OpValue"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTarget26"; + let ParserMatchClass = MipsJumpTargetAsmOperand; +} + //===----------------------------------------------------------------------===// // // Instruction Encodings // //===----------------------------------------------------------------------===// +class BALC_ENC : BRANCH_OFF26_FM<0b111010>; +class BC_ENC : BRANCH_OFF26_FM<0b110010>; +class BEQC_ENC : CMP_BRANCH_OFF16_FM<0b001000>; +class BNEC_ENC : CMP_BRANCH_OFF16_FM<0b011000>; + +class BLTZC_ENC : CMP_BRANCH_OFF16_FM<0b010111>; +class BGEZC_ENC : CMP_BRANCH_OFF16_FM<0b010110>; + +class BLEZC_ENC : CMP_BRANCH_RT_OFF16_FM<0b010110>; +class BGTZC_ENC : CMP_BRANCH_RT_OFF16_FM<0b010111>; + +class BEQZC_ENC : CMP_BRANCH_OFF21_FM<0b110110>; +class BNEZC_ENC : CMP_BRANCH_OFF21_FM<0b111110>; + class MUH_ENC : SPECIAL_3R_FM<0b00011, 0b011000>; class MUHU_ENC : SPECIAL_3R_FM<0b00011, 0b011001>; class MUL_R6_ENC : SPECIAL_3R_FM<0b00010, 0b011000>; @@ -71,6 +99,65 @@ // //===----------------------------------------------------------------------===// +class BRANCH_DESC_BASE { + string AsmString = asm_str; + dag InOperandList = in_ops; + dag OutOperandList = (outs); + list Pattern = []; + bit isBranch = 1; + bit isTerminator = 1; + bit hasDelaySlot = 0; +} + +class BC_DESC_BASE + : BRANCH_DESC_BASE { + bit isBarrier = 1; +} + +class CMP_BC_DESC_BASE + : BRANCH_DESC_BASE { + list Defs = [AT]; +} + +class CMP_CBR_EQNE_Z_DESC_BASE + : BRANCH_DESC_BASE { + list Defs = [AT]; +} + +class CMP_CBR_RT_Z_DESC_BASE + : BRANCH_DESC_BASE { + list Defs = [AT]; +} + +class BALC_DESC : BC_DESC_BASE<"balc", brtarget26> { + bit isCall = 1; + list Defs = [RA]; +} + +class BC_DESC : BC_DESC_BASE<"bc", brtarget26>; +class BEQC_DESC : CMP_BC_DESC_BASE<"beqc", brtarget, GPR32Opnd>; +class BNEC_DESC : CMP_BC_DESC_BASE<"bnec", brtarget, GPR32Opnd>; + +class BLTZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bltzc", brtarget, GPR32Opnd> { + string Constraints = "$rs = $rt"; +} + +class BGEZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bgezc", brtarget, GPR32Opnd> { + string Constraints = "$rs = $rt"; +} + +class BLEZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"blezc", brtarget, GPR32Opnd>; +class BGTZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bgtzc", brtarget, GPR32Opnd>; + +class BEQZC_DESC : CMP_CBR_EQNE_Z_DESC_BASE<"beqzc", brtarget21, GPR32Opnd>; +class BNEZC_DESC : CMP_CBR_EQNE_Z_DESC_BASE<"bnezc", brtarget21, GPR32Opnd>; + class MUL_R6_DESC_BASE { dag OutOperandList = (outs GPROpnd:$rd); dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt); @@ -94,31 +181,31 @@ def ALUIPC; def AUI; def AUIPC; -def BALC; +def BALC : BALC_ENC, BALC_DESC, ISA_MIPS32R6; def BC1EQZ; def BC1NEZ; def BC2EQZ; def BC2NEZ; -def BC; -def BEQC; +def BC : BC_ENC, BC_DESC, ISA_MIPS32R6; +def BEQC : BEQC_ENC, BEQC_DESC, ISA_MIPS32R6; def BEQZALC; -def BEQZC; +def BEQZC : BEQZC_ENC, BEQZC_DESC, ISA_MIPS32R6; def BGEC; // Also aliased to blec with operands swapped def BGEUC; // Also aliased to bleuc with operands swapped def BGEZALC; -def BGEZC; +def BGEZC : BGEZC_ENC, BGEZC_DESC, ISA_MIPS32R6; def BGTZALC; -def BGTZC; +def BGTZC : BGTZC_ENC, BGTZC_DESC, ISA_MIPS32R6; def BITSWAP; // Known as BITREV in DSP ASE def BLEZALC; -def BLEZC; +def BLEZC : BLEZC_ENC, BLEZC_DESC, ISA_MIPS32R6; def BLTC; // Also aliased to bgtc with operands swapped def BLTUC; // Also aliased to bgtuc with operands swapped def BLTZALC; -def BLTZC; -def BNEC; +def BLTZC : BLTZC_ENC, BLTZC_DESC, ISA_MIPS32R6; +def BNEC : BNEC_ENC, BNEC_DESC, ISA_MIPS32R6; def BNEZALC; -def BNEZC; +def BNEZC : BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6; def BNVC; def BOVC; def CLASS_D; Index: lib/Target/Mips/MipsCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MipsCodeEmitter.cpp +++ lib/Target/Mips/MipsCodeEmitter.cpp @@ -110,6 +110,11 @@ unsigned getBranchTargetOpValueMM(const MachineInstr &MI, unsigned OpNo) const; + unsigned getBranchTarget21OpValue(const MachineInstr &MI, + unsigned OpNo) const; + unsigned getBranchTarget26OpValue(const MachineInstr &MI, + unsigned OpNo) const; + unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getMemEncodingMMImm12(const MachineInstr &MI, unsigned OpNo) const; @@ -202,6 +207,18 @@ return 0; } +unsigned MipsCodeEmitter::getBranchTarget21OpValue(const MachineInstr &MI, + unsigned OpNo) const { + llvm_unreachable("Unimplemented function."); + return 0; +} + +unsigned MipsCodeEmitter::getBranchTarget26OpValue(const MachineInstr &MI, + unsigned OpNo) const { + llvm_unreachable("Unimplemented function."); + return 0; +} + unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const { MachineOperand MO = MI.getOperand(OpNo); Index: test/MC/Mips/mips32r6/valid.s =================================================================== --- test/MC/Mips/mips32r6/valid.s +++ test/MC/Mips/mips32r6/valid.s @@ -8,3 +8,13 @@ muh $2,$3,$4 # CHECK: muh $2, $3, $4 # encoding: [0x00,0x64,0x10,0xd8] mulu $2,$3,$4 # CHECK: mulu $2, $3, $4 # encoding: [0x00,0x64,0x10,0x99] muhu $2,$3,$4 # CHECK: muhu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xd9] + balc 14572256 # CHECK: balc 14572256 # encoding: [0xe8,0x37,0x96,0xb8] + bc 14572256 # CHECK: bc 14572256 # encoding: [0xc8,0x37,0x96,0xb8] + beqc $5, $6, 256 # CHECK: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40] + bnec $5, $6, 256 # CHECK: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40] + beqzc $5, 72256 # CHECK: beqzc $5, 72256 # encoding: [0xd8,0xa0,0x46,0x90] + bnezc $5, 72256 # CHECK: bnezc $5, 72256 # encoding: [0xf8,0xa0,0x46,0x90] + bltzc $5, 256 # CHECK: bltzc $5, 256 # encoding: [0x5c,0xa5,0x00,0x40] + bgezc $5, 256 # CHECK: bgezc $5, 256 # encoding: [0x58,0xa5,0x00,0x40] + blezc $5, 256 # CHECK: blezc $5, 256 # encoding: [0x58,0x05,0x00,0x40] + bgtzc $5, 256 # CHECK: bgtzc $5, 256 # encoding: [0x5c,0x05,0x00,0x40] Index: test/MC/Mips/mips64r6/valid.s =================================================================== --- test/MC/Mips/mips64r6/valid.s +++ test/MC/Mips/mips64r6/valid.s @@ -12,3 +12,13 @@ dmuh $2,$3,$4 # CHECK: dmuh $2, $3, $4 # encoding: [0x00,0x64,0x10,0xf8] dmulu $2,$3,$4 # CHECK: dmulu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xb9] dmuhu $2,$3,$4 # CHECK: dmuhu $2, $3, $4 # encoding: [0x00,0x64,0x10,0xf9] + balc 14572256 # CHECK: balc 14572256 # encoding: [0xe8,0x37,0x96,0xb8] + bc 14572256 # CHECK: bc 14572256 # encoding: [0xc8,0x37,0x96,0xb8] + beqc $5, $6, 256 # CHECK: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40] + bnec $5, $6, 256 # CHECK: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40] + beqzc $5, 72256 # CHECK: beqzc $5, 72256 # encoding: [0xd8,0xa0,0x46,0x90] + bnezc $5, 72256 # CHECK: bnezc $5, 72256 # encoding: [0xf8,0xa0,0x46,0x90] + bltzc $5, 256 # CHECK: bltzc $5, 256 # encoding: [0x5c,0xa5,0x00,0x40] + bgezc $5, 256 # CHECK: bgezc $5, 256 # encoding: [0x58,0xa5,0x00,0x40] + blezc $5, 256 # CHECK: blezc $5, 256 # encoding: [0x58,0x05,0x00,0x40] + bgtzc $5, 256 # CHECK: bgtzc $5, 256 # encoding: [0x5c,0x05,0x00,0x40]