Index: llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -194,6 +194,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, @@ -1827,6 +1832,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: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ llvm/trunk/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: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -230,6 +230,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: llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrFormats.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrFormats.td +++ llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrFormats.td @@ -242,3 +242,12 @@ let Inst{13-6} = op; let Inst{5-0} = 0b111100; } + +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: llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MicroMipsDSPInstrInfo.td @@ -155,6 +155,11 @@ class SHILO_MM_ENC : POOL32A_4B0SHIFT6AC4B0_FMT<"shilo", 0b0000011101>; class SHILOV_MM_ENC : POOL32A_5B01RAC_FMT<"shilov", 0b01001001>; class WRDSP_MM_ENC : POOL32A_1RMASK7_FMT<"wrdsp", 0b01011001>; +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; +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: llvm/trunk/lib/Target/Mips/MipsDSPInstrFormats.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsDSPInstrFormats.td +++ llvm/trunk/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: llvm/trunk/lib/Target/Mips/MipsDSPInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsDSPInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MipsDSPInstrInfo.td @@ -1115,7 +1115,7 @@ def SUBQ_S_W : DspMMRel, 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 : DspMMRel, 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; @@ -1154,7 +1154,7 @@ def MULEQ_S_W_PHL : DspMMRel, MULEQ_S_W_PHL_ENC, MULEQ_S_W_PHL_DESC; def MULEQ_S_W_PHR : DspMMRel, MULEQ_S_W_PHR_ENC, MULEQ_S_W_PHR_DESC; def MULQ_RS_PH : DspMMRel, 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 : DspMMRel, MAQ_S_W_PHL_ENC, MAQ_S_W_PHL_DESC; def MAQ_S_W_PHR : DspMMRel, MAQ_S_W_PHR_ENC, MAQ_S_W_PHR_DESC; def MAQ_SA_W_PHL : DspMMRel, MAQ_SA_W_PHL_ENC, MAQ_SA_W_PHL_DESC; @@ -1197,7 +1197,7 @@ def LWX : DspMMRel, LWX_ENC, LWX_DESC; def LHX : DspMMRel, LHX_ENC, LHX_DESC; def LBUX : DspMMRel, LBUX_ENC, LBUX_DESC; -def BPOSGE32 : BPOSGE32_ENC, BPOSGE32_DESC; +def BPOSGE32 : DspMMRel, BPOSGE32_ENC, BPOSGE32_DESC; def INSV : DspMMRel, INSV_ENC, INSV_DESC; def EXTP : DspMMRel, EXTP_ENC, EXTP_DESC; def EXTPV : DspMMRel, EXTPV_ENC, EXTPV_DESC; @@ -1253,7 +1253,7 @@ def DPSX_W_PH : DspMMRel, DPSX_W_PH_ENC, DPSX_W_PH_DESC, ISA_DSPR2; def DPSQX_S_W_PH : DspMMRel, DPSQX_S_W_PH_ENC, DPSQX_S_W_PH_DESC, ISA_DSPR2; def DPSQX_SA_W_PH : DspMMRel, DPSQX_SA_W_PH_ENC, DPSQX_SA_W_PH_DESC, ISA_DSPR2; -def MULSA_W_PH : MULSA_W_PH_ENC, MULSA_W_PH_DESC, ISA_DSPR2; +def MULSA_W_PH : DspMMRel, MULSA_W_PH_ENC, MULSA_W_PH_DESC, ISA_DSPR2; def PRECR_QB_PH : DspMMRel, PRECR_QB_PH_ENC, PRECR_QB_PH_DESC, ISA_DSPR2; def PRECR_SRA_PH_W : DspMMRel, PRECR_SRA_PH_W_ENC, PRECR_SRA_PH_W_DESC, ISA_DSPR2; def PRECR_SRA_R_PH_W : DspMMRel, PRECR_SRA_R_PH_W_ENC, PRECR_SRA_R_PH_W_DESC, ISA_DSPR2; @@ -1263,7 +1263,7 @@ def SHRAV_R_QB : DspMMRel, SHRAV_R_QB_ENC, SHRAV_R_QB_DESC, ISA_DSPR2; def SHRL_PH : DspMMRel, SHRL_PH_ENC, SHRL_PH_DESC, ISA_DSPR2; def SHRLV_PH : DspMMRel, SHRLV_PH_ENC, SHRLV_PH_DESC, ISA_DSPR2; -def APPEND : APPEND_ENC, APPEND_DESC, ISA_DSPR2; +def APPEND : DspMMRel, APPEND_ENC, APPEND_DESC, ISA_DSPR2; def BALIGN : BALIGN_ENC, BALIGN_DESC, ISA_DSPR2; def PREPEND : DspMMRel, PREPEND_ENC, PREPEND_DESC, ISA_DSPR2; Index: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td @@ -622,6 +622,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: llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp +++ llvm/trunk/lib/Target/Mips/MipsSEISelLowering.cpp @@ -2947,6 +2947,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: llvm/trunk/test/MC/Disassembler/Mips/micromips-dsp/valid.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Mips/micromips-dsp/valid.txt +++ llvm/trunk/test/MC/Disassembler/Mips/micromips-dsp/valid.txt @@ -101,3 +101,5 @@ 0x00 0x01 0x82 0x7c # CHECK: mthlip $1, $ac2 0x00 0xa7 0xd6 0x7c # CHECK: wrdsp $5 0x00 0xa0 0x96 0x7c # CHECK: wrdsp $5, 2 +0x00 0xc5 0x22 0x95 # CHECK: modsub $4, $5, $6 +0x00 0x43 0x3c 0xbc # CHECK: mulsaq_s.w.ph $ac0, $3, $2 Index: llvm/trunk/test/MC/Disassembler/Mips/micromips-dspr2/valid.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Mips/micromips-dspr2/valid.txt +++ llvm/trunk/test/MC/Disassembler/Mips/micromips-dspr2/valid.txt @@ -123,3 +123,5 @@ 0x00 0x22 0x1a 0x55 # CHECK: prepend $1, $2, 3 0x00 0xa7 0xd6 0x7c # CHECK: wrdsp $5 0x00 0xa0 0x96 0x7c # CHECK: wrdsp $5, 2 +0x00 0x64 0x2a 0x15 # CHECK: append $3, $4, 5 +0x00 0x43 0x2c 0xbc # CHECK: mulsa.w.ph $ac0, $3, $2 Index: llvm/trunk/test/MC/Disassembler/Mips/micromips-dspr3/valid.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Mips/micromips-dspr3/valid.txt +++ llvm/trunk/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: llvm/trunk/test/MC/Mips/micromips-dsp/valid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips-dsp/valid.s +++ llvm/trunk/test/MC/Mips/micromips-dsp/valid.s @@ -103,3 +103,5 @@ wrdsp $5 # CHECK: wrdsp $5 # encoding: [0x00,0xa7,0xd6,0x7c] wrdsp $5, 2 # CHECK: wrdsp $5, 2 # encoding: [0x00,0xa0,0x96,0x7c] wrdsp $5, 31 # CHECK: wrdsp $5 # encoding: [0x00,0xa7,0xd6,0x7c] + 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: llvm/trunk/test/MC/Mips/micromips-dspr2/invalid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips-dspr2/invalid.s +++ llvm/trunk/test/MC/Mips/micromips-dspr2/invalid.s @@ -7,3 +7,9 @@ shra_r.qb $3, $4, -1 # CHECK: :[[@LINE]]:21: error: expected 3-bit unsigned immediate shrl.ph $3, $4, 16 # CHECK: :[[@LINE]]:19: error: expected 4-bit unsigned immediate shrl.ph $3, $4, -1 # CHECK: :[[@LINE]]:19: error: expected 4-bit unsigned immediate + append $3, $4, 32 # CHECK: :[[@LINE]]:18: error: expected 5-bit unsigned immediate + append $3, $4, -1 # CHECK: :[[@LINE]]:18: error: expected 5-bit unsigned immediate + mulsa.w.ph $8, $3, $2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction + mulsa.w.ph $31, $3, $2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction + mulsaq_s.w.ph $8, $3, $2 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction + mulsaq_s.w.ph $31, $3, $2 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction Index: llvm/trunk/test/MC/Mips/micromips-dspr2/valid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips-dspr2/valid.s +++ llvm/trunk/test/MC/Mips/micromips-dspr2/valid.s @@ -125,3 +125,5 @@ wrdsp $5 # CHECK: wrdsp $5 # encoding: [0x00,0xa7,0xd6,0x7c] wrdsp $5, 2 # CHECK: wrdsp $5, 2 # encoding: [0x00,0xa0,0x96,0x7c] wrdsp $5, 31 # CHECK: wrdsp $5 # encoding: [0x00,0xa7,0xd6,0x7c] + 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: llvm/trunk/test/MC/Mips/micromips-dspr3/valid.s =================================================================== --- llvm/trunk/test/MC/Mips/micromips-dspr3/valid.s +++ llvm/trunk/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]