Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -193,6 +193,11 @@ uint64_t Address, const void *Decoder); +static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1766,6 +1771,15 @@ return MCDisassembler::Success; } +static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + int32_t BranchOffset = (SignExtend32<16>(Offset) * 2); + Inst.addOperand(MCOperand::createImm(BranchOffset)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeJumpTarget(MCInst &Inst, unsigned Insn, uint64_t Address, Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -102,6 +102,13 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + // getBranchTargetOpValue1SImm16 - Return binary encoding of the branch + // target operand. If the machine operand requires relocation, + // record the relocation and return zero. + unsigned getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getBranchTarget7OpValue - Return binary encoding of the microMIPS branch // target 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 @@ -237,6 +237,29 @@ return 0; } +/// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTargetOpValue1SImm16(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() && + "getBranchTargetOpValue expects only expressions or immediates"); + + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_Mips_PC16))); + return 0; +} + /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. Index: lib/Target/Mips/MicroMipsDSPInstrFormats.td =================================================================== --- lib/Target/Mips/MicroMipsDSPInstrFormats.td +++ lib/Target/Mips/MicroMipsDSPInstrFormats.td @@ -102,3 +102,12 @@ let Inst{10} = 0b0; let Inst{9-0} = op; } + +class POOL32I_IMMB0_FMT op> : MMDSPInst { + bits<16> offset; + + let Inst{31-26} = 0b010000; + let Inst{25-21} = op; + let Inst{20-16} = 0; + let Inst{15-0} = offset; +} Index: lib/Target/Mips/MicroMipsDSPInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsDSPInstrInfo.td +++ lib/Target/Mips/MicroMipsDSPInstrInfo.td @@ -55,6 +55,11 @@ class SHLL_S_W_MM_ENC : POOL32A_2RSA5B0_FMT<"shll_s.w", 0b1111110101>; class SHRA_QB_MMR2_ENC : POOL32A_2RSA3_FMT<"shra.qb", 0b0000111>; class SHRA_R_QB_MMR2_ENC : POOL32A_2RSA3_FMT<"shra_r.qb", 0b1000111>; +class APPEND_MMR2_ENC : POOL32A_2RSA5B0_FMT<"append", 0b1000010101>; +class MODSUB_MM_ENC : POOL32A_3RB0_FMT<"modsub", 0b1010010101>; +class MULSA_W_PH_MMR2_ENC : POOL32A_2RAC_FMT<"mulsa.w.ph", 0b10110010>; +class MULSAQ_S_W_PH_MM_ENC : POOL32A_2RAC_FMT<"mulsaq_s.w.ph", 0b11110010>; +class BPOSGE32C_MMR3_ENC : POOL32I_IMMB0_FMT<"bposge32c", 0b11001>; // Instruction desc. class ABSQ_S_PH_MM_R2_DESC_BASE, Defs<[DSPOutFlag22]>; +class BPOSGE32C_MMR3_DESC { + dag OutOperandList = (outs); + dag InOperandList = (ins brtarget1SImm16:$offset); + string AsmString = !strconcat("bposge32c", "\t$offset"); + InstrItinClass Itinerary = NoItinerary; + bit isBranch = 1; + bit isTerminator = 1; + bit hasDelaySlot = 0; +} + // Instruction defs. // microMIPS DSP Rev 1 def ADDQ_PH_MM : DspMMRel, ADDQ_PH_MM_ENC, ADDQ_PH_DESC; @@ -148,6 +163,8 @@ def SHLLV_QB_MM : DspMMRel, SHLLV_QB_MM_ENC, SHLLV_QB_MM_DESC; def SHLLV_S_W_MM : DspMMRel, SHLLV_S_W_MM_ENC, SHLLV_S_W_MM_DESC; def SHLL_S_W_MM : DspMMRel, SHLL_S_W_MM_ENC, SHLL_S_W_MM_DESC; +def MODSUB_MM : DspMMRel, MODSUB_MM_ENC, MODSUB_DESC; +def MULSAQ_S_W_PH_MM : DspMMRel, MULSAQ_S_W_PH_MM_ENC, MULSAQ_S_W_PH_DESC; // microMIPS DSP Rev 2 def ABSQ_S_QB_MMR2 : DspMMRel, ABSQ_S_QB_MMR2_ENC, ABSQ_S_QB_MMR2_DESC, ISA_DSPR2; @@ -168,3 +185,8 @@ def SHRA_QB_MMR2 : DspMMRel, SHRA_QB_MMR2_ENC, SHRA_QB_MMR2_DESC, ISA_DSPR2; def SHRA_R_QB_MMR2 : DspMMRel, SHRA_R_QB_MMR2_ENC, SHRA_R_QB_MMR2_DESC, ISA_DSPR2; +def APPEND_MMR2 : DspMMRel, APPEND_MMR2_ENC, APPEND_DESC, ISA_DSPR2; +def MULSA_W_PH_MMR2 : DspMMRel, MULSA_W_PH_MMR2_ENC, MULSA_W_PH_DESC, ISA_DSPR2; +// microMIPS DSP Rev 3 +def BPOSGE32C_MMR3 : DspMMRel, BPOSGE32C_MMR3_ENC, BPOSGE32C_MMR3_DESC, + ISA_DSPR3; Index: lib/Target/Mips/MipsDSPInstrFormats.td =================================================================== --- lib/Target/Mips/MipsDSPInstrFormats.td +++ lib/Target/Mips/MipsDSPInstrFormats.td @@ -32,6 +32,10 @@ list InsnPredicates = [HasDSPR2]; } +class ISA_DSPR3 { + list InsnPredicates = [HasDSPR3]; +} + // Fields. class Field6 val> { bits<6> V = val; Index: lib/Target/Mips/MipsDSPInstrInfo.td =================================================================== --- lib/Target/Mips/MipsDSPInstrInfo.td +++ lib/Target/Mips/MipsDSPInstrInfo.td @@ -1094,7 +1094,7 @@ def SUBQ_S_W : SUBQ_S_W_ENC, SUBQ_S_W_DESC; def ADDSC : DspMMRel, ADDSC_ENC, ADDSC_DESC; def ADDWC : DspMMRel, ADDWC_ENC, ADDWC_DESC; -def MODSUB : MODSUB_ENC, MODSUB_DESC; +def MODSUB : DspMMRel, MODSUB_ENC, MODSUB_DESC; def RADDU_W_QB : RADDU_W_QB_ENC, RADDU_W_QB_DESC; def ABSQ_S_PH : DspMMRel, ABSQ_S_PH_ENC, ABSQ_S_PH_DESC; def ABSQ_S_W : DspMMRel, ABSQ_S_W_ENC, ABSQ_S_W_DESC; @@ -1133,7 +1133,7 @@ def MULEQ_S_W_PHL : MULEQ_S_W_PHL_ENC, MULEQ_S_W_PHL_DESC; def MULEQ_S_W_PHR : MULEQ_S_W_PHR_ENC, MULEQ_S_W_PHR_DESC; def MULQ_RS_PH : MULQ_RS_PH_ENC, MULQ_RS_PH_DESC; -def MULSAQ_S_W_PH : MULSAQ_S_W_PH_ENC, MULSAQ_S_W_PH_DESC; +def MULSAQ_S_W_PH : DspMMRel, MULSAQ_S_W_PH_ENC, MULSAQ_S_W_PH_DESC; def MAQ_S_W_PHL : MAQ_S_W_PHL_ENC, MAQ_S_W_PHL_DESC; def MAQ_S_W_PHR : MAQ_S_W_PHR_ENC, MAQ_S_W_PHR_DESC; def MAQ_SA_W_PHL : MAQ_SA_W_PHL_ENC, MAQ_SA_W_PHL_DESC; @@ -1232,7 +1232,7 @@ def DPSX_W_PH : DPSX_W_PH_ENC, DPSX_W_PH_DESC; def DPSQX_S_W_PH : DPSQX_S_W_PH_ENC, DPSQX_S_W_PH_DESC; def DPSQX_SA_W_PH : DPSQX_SA_W_PH_ENC, DPSQX_SA_W_PH_DESC; -def MULSA_W_PH : MULSA_W_PH_ENC, MULSA_W_PH_DESC; +def MULSA_W_PH : DspMMRel, MULSA_W_PH_ENC, MULSA_W_PH_DESC; def PRECR_QB_PH : PRECR_QB_PH_ENC, PRECR_QB_PH_DESC; def PRECR_SRA_PH_W : PRECR_SRA_PH_W_ENC, PRECR_SRA_PH_W_DESC; def PRECR_SRA_R_PH_W : PRECR_SRA_R_PH_W_ENC, PRECR_SRA_R_PH_W_DESC; @@ -1242,7 +1242,7 @@ def SHRAV_R_QB : SHRAV_R_QB_ENC, SHRAV_R_QB_DESC; def SHRL_PH : SHRL_PH_ENC, SHRL_PH_DESC; def SHRLV_PH : SHRLV_PH_ENC, SHRLV_PH_DESC; -def APPEND : APPEND_ENC, APPEND_DESC; +def APPEND : DspMMRel, APPEND_ENC, APPEND_DESC; def BALIGN : BALIGN_ENC, BALIGN_DESC; def PREPEND : PREPEND_ENC, PREPEND_DESC; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -399,6 +399,12 @@ let DecoderMethod = "DecodeBranchTarget"; let ParserMatchClass = MipsJumpTargetAsmOperand; } +def brtarget1SImm16 : Operand { + let EncoderMethod = "getBranchTargetOpValue1SImm16"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTarget1SImm16"; + let ParserMatchClass = MipsJumpTargetAsmOperand; +} def calltarget : Operand { let EncoderMethod = "getJumpTargetOpValue"; let ParserMatchClass = MipsJumpTargetAsmOperand; Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -2949,6 +2949,8 @@ // Insert the real bposge32 instruction to $BB. BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); + // Insert the real bposge32c instruction to $BB. + BuildMI(BB, DL, TII->get(Mips::BPOSGE32C_MMR3)).addMBB(TBB); // Fill $FBB. unsigned VR2 = RegInfo.createVirtualRegister(RC); Index: test/MC/Disassembler/Mips/micromips-dsp/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips-dsp/valid.txt +++ test/MC/Disassembler/Mips/micromips-dsp/valid.txt @@ -28,3 +28,5 @@ 0x00 0x85 0x1b 0x95 # CHECK: shllv.qb $3, $4, $5 0x00 0x85 0x1b 0xd5 # CHECK: shllv_s.w $3, $4, $5 0x00 0x64 0x2b 0xf5 # CHECK: shll_s.w $3, $4, 5 +0x00 0xc5 0x22 0x95 # CHECK: modsub $4, $5, $6 +0x00 0x43 0x3c 0xbc # CHECK: mulsaq_s.w.ph $ac0, $3, $2 Index: test/MC/Disassembler/Mips/micromips-dspr2/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips-dspr2/valid.txt +++ test/MC/Disassembler/Mips/micromips-dspr2/valid.txt @@ -15,3 +15,5 @@ 0x00 0x22 0xd0 0xbc # CHECK: dpax.w.ph $ac3, $2, $1 0x00 0x64 0xa1 0xfc # CHECK: shra.qb $3, $4, 5 0x00 0x64 0xb1 0xfc # CHECK: shra_r.qb $3, $4, 5 +0x00 0x64 0x2a 0x15 # CHECK: append $3, $4, 5 +0x00 0x43 0x2c 0xbc # CHECK: mulsa.w.ph $ac0, $3, $2 Index: test/MC/Disassembler/Mips/micromips-dspr3/valid.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/Mips/micromips-dspr3/valid.txt @@ -0,0 +1,3 @@ +# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips32r6 -mattr=micromips -mattr=+dspr3 | FileCheck %s + +0x43 0x20 0x00 0xab # CHECK: bposge32c 342 Index: test/MC/Mips/micromips-dsp/valid.s =================================================================== --- test/MC/Mips/micromips-dsp/valid.s +++ test/MC/Mips/micromips-dsp/valid.s @@ -29,3 +29,5 @@ shllv.qb $3, $4, $5 # CHECK: shllv.qb $3, $4, $5 # encoding: [0x00,0x85,0x1b,0x95] shllv_s.w $3, $4, $5 # CHECK: shllv_s.w $3, $4, $5 # encoding: [0x00,0x85,0x1b,0xd5] shll_s.w $3, $4, 5 # CHECK: shll_s.w $3, $4, 5 # encoding: [0x00,0x64,0x2b,0xf5] + modsub $4, $5, $6 # CHECK: modsub $4, $5, $6 # encoding: [0x00,0xc5,0x22,0x95] + mulsaq_s.w.ph $ac0, $3, $2 # CHECK: mulsaq_s.w.ph $ac0, $3, $2 # encoding: [0x00,0x43,0x3c,0xbc] Index: test/MC/Mips/micromips-dspr2/valid.s =================================================================== --- test/MC/Mips/micromips-dspr2/valid.s +++ test/MC/Mips/micromips-dspr2/valid.s @@ -16,3 +16,5 @@ dpax.w.ph $ac3, $2, $1 # CHECK: dpax.w.ph $ac3, $2, $1 # encoding: [0x00,0x22,0xd0,0xbc] shra.qb $3, $4, 5 # CHECK: shra.qb $3, $4, 5 # encoding: [0x00,0x64,0xa1,0xfc] shra_r.qb $3, $4, 5 # CHECK: shra_r.qb $3, $4, 5 # encoding: [0x00,0x64,0xb1,0xfc] + append $3, $4, 5 # CHECK: append $3, $4, 5 # encoding: [0x00,0x64,0x2a,0x15] + mulsa.w.ph $ac0, $3, $2 # CHECK: mulsa.w.ph $ac0, $3, $2 # encoding: [0x00,0x43,0x2c,0xbc] Index: test/MC/Mips/micromips-dspr3/valid.s =================================================================== --- /dev/null +++ test/MC/Mips/micromips-dspr3/valid.s @@ -0,0 +1,4 @@ +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r6 -mattr=micromips -mattr=+dspr3 | FileCheck %s + + .set noat + bposge32c 342 # CHECK: bposge32c 342 # encoding: [0x43,0x20,0x00,0xab]