Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -981,6 +981,16 @@ return MipsInsts[Opcode]; } +static bool hasShortDelaySlot(unsigned Opcode) { + switch (Opcode) { + case Mips::JALS_MM: + case Mips::JALRS_MM: + return true; + default: + return false; + } +} + bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions) { const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); @@ -1050,10 +1060,16 @@ // emit a NOP after it. Instructions.push_back(Inst); MCInst NopInst; - NopInst.setOpcode(Mips::SLL); - NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); - NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); - NopInst.addOperand(MCOperand::CreateImm(0)); + if (hasShortDelaySlot(Inst.getOpcode())) { + NopInst.setOpcode(Mips::MOVE16_MM); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + } else { + NopInst.setOpcode(Mips::SLL); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + NopInst.addOperand(MCOperand::CreateImm(0)); + } Instructions.push_back(NopInst); return false; } Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -104,6 +104,19 @@ let Defs = [RA]; } +// MicroMIPS Jump and Link (Call) - Short Delay Slot +let isCall = 1, hasDelaySlot = 1, Defs = [RA] in { + class JumpLinkMM : + InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), + [], IIBranch, FrmJ, opstr> { + let DecoderMethod = "DecodeJumpTargetMM"; + } + + class JumpLinkRegMM: + InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), + [], IIBranch, FrmR>; +} + def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>; def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>; def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>; @@ -263,6 +276,10 @@ def JR_MM : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>; def JALR_MM : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM_MM<0x03c>; + /// Jump Instructions - Short Delay Slot + def JALS_MM : JumpLinkMM<"jals", calltarget_mm>, J_FM_MM<0x1d>; + def JALRS_MM : JumpLinkRegMM<"jalrs", GPR32Opnd>, JALR_FM_MM<0x13c>; + /// Branch Instructions def BEQ_MM : MMRel, CBranch<"beq", brtarget_mm, seteq, GPR32Opnd>, BEQ_FM_MM<0x25>; Index: test/MC/Mips/micromips-jump-instructions.s =================================================================== --- test/MC/Mips/micromips-jump-instructions.s +++ test/MC/Mips/micromips-jump-instructions.s @@ -19,6 +19,10 @@ # CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] # CHECK-EL: jr $7 # encoding: [0x07,0x00,0x3c,0x0f] # CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EL: jals 1328 # encoding: [0x00,0x74,0x98,0x02] +# CHECK-EL: move $zero, $zero # encoding: [0x00,0x0c] +# CHECK-EL: jalrs $ra, $6 # encoding: [0xe6,0x03,0x3c,0x4f] +# CHECK-EL: move $zero, $zero # encoding: [0x00,0x0c] #------------------------------------------------------------------------------ # Big endian #------------------------------------------------------------------------------ @@ -32,9 +36,15 @@ # CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] # CHECK-EB: jr $7 # encoding: [0x00,0x07,0x0f,0x3c] # CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00] +# CHECK-EB: jals 1328 # encoding: [0x74,0x00,0x02,0x98] +# CHECK-EB: move $zero, $zero # encoding: [0x0c,0x00] +# CHECK-EB: jalrs $ra, $6 # encoding: [0x03,0xe6,0x4f,0x3c] +# CHECK-EB: move $zero, $zero # encoding: [0x0c,0x00] j 1328 jal 1328 jalr $ra, $6 jr $7 j $7 + jals 1328 + jalrs $ra, $6