Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1556,6 +1556,19 @@ Instructions); } +void emitRRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, + MCOperand Op2, SMLoc IDLoc, + SmallVectorImpl &Instructions) { + MCInst tmpInst; + tmpInst.setOpcode(Opcode); + tmpInst.addOperand(MCOperand::createReg(Reg0)); + tmpInst.addOperand(MCOperand::createReg(Reg1)); + tmpInst.addOperand(MCOperand::createReg(Reg2)); + tmpInst.addOperand(Op2); + tmpInst.setLoc(IDLoc); + Instructions.push_back(tmpInst); +} + void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, SMLoc IDLoc, SmallVectorImpl &Instructions) { if (ShiftAmount >= 32) { @@ -2614,13 +2627,21 @@ // 1st operand is either the source or destination register. assert(Inst.getOperand(0).isReg() && "expected register operand kind"); unsigned RegOpNum = Inst.getOperand(0).getReg(); - // 2nd operand is the base register. + bool IsSC = Inst.getOpcode() == Mips::SCD || Inst.getOpcode() == Mips::SC; + unsigned BaseRegNum; assert(Inst.getOperand(1).isReg() && "expected register operand kind"); - unsigned BaseRegNum = Inst.getOperand(1).getReg(); - // 3rd operand is either an immediate or expression. + if (IsSC) + assert(Inst.getOperand(2).isReg() && "expected register operand kind"); + BaseRegNum = IsSC ? Inst.getOperand(2).getReg() : Inst.getOperand(1).getReg(); + // The last operand is either an immediate or expression. if (isImmOpnd) { - assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); - unsigned ImmOffset = Inst.getOperand(2).getImm(); + unsigned ImmOffset; + IsSC ? assert(Inst.getOperand(3).isImm() && + "expected immediate operand kind") + : assert(Inst.getOperand(2).isImm() && + "expected immediate operand kind"); + ImmOffset = + IsSC ? Inst.getOperand(3).getImm() : Inst.getOperand(2).getImm(); unsigned LoOffset = ImmOffset & 0x0000ffff; unsigned HiOffset = (ImmOffset & 0xffff0000) >> 16; // If msb of LoOffset is 1(negative number) we must increment HiOffset. @@ -2677,7 +2698,10 @@ emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions); // And finally, create original instruction with low part // of offset and new base. - emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum, LoOperand, IDLoc, Instructions); + IsSC ? emitRRRX(Inst.getOpcode(), RegOpNum, RegOpNum, TmpRegNum, LoOperand, + IDLoc, Instructions) + : emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum, LoOperand, IDLoc, + Instructions); } bool Index: test/MC/Mips/sc.s =================================================================== --- test/MC/Mips/sc.s +++ test/MC/Mips/sc.s @@ -0,0 +1,39 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -show-encoding | FileCheck %s + +sc $2, 128($sp) +# CHECK: sc $2, 128($sp) # encoding: [0x80,0x00,0xa2,0xe3] + +sc $2, -128($sp) +# CHECK: sc $2, -128($sp) # encoding: [0x80,0xff,0xa2,0xe3] + +sc $2, 256($sp) +# CHECK: sc $2, 256($sp) # encoding: [0x00,0x01,0xa2,0xe3] + +sc $2, -257($sp) +# CHECK: sc $2, -257($sp) # encoding: [0xff,0xfe,0xa2,0xe3] + +sc $2, 32767($sp) +# CHECK: sc $2, 32767($sp) # encoding: [0xff,0x7f,0xa2,0xe3] + +sc $2, 32768($sp) +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: sc $2, 32768($1) # encoding: [0x00,0x80,0x22,0xe0] + +sc $2, -32768($sp) +# CHECK: sc $2, -32768($sp) # encoding: [0x00,0x80,0xa2,0xe3] + +sc $2, -32769($sp) +# CHECK: lui $1, 65535 # encoding: [0xff,0xff,0x01,0x3c] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: sc $2, 32767($1) # encoding: [0xff,0x7f,0x22,0xe0] + +sc $2, 655987($sp) +# CHECK: lui $1, 10 # encoding: [0x0a,0x00,0x01,0x3c] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: sc $2, 627($1) # encoding: [0x73,0x02,0x22,0xe0] + +sc $2, -655987($sp) +# CHECK: lui $1, 65526 # encoding: [0xf6,0xff,0x01,0x3c] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: sc $2, 64909($1) # encoding: [0x8d,0xfd,0x22,0xe0] Index: test/MC/Mips/scd.s =================================================================== --- test/MC/Mips/scd.s +++ test/MC/Mips/scd.s @@ -0,0 +1,39 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips64r2 -show-encoding | FileCheck %s + +scd $2, 128($sp) +# CHECK: scd $2, 128($sp) # encoding: [0x80,0x00,0xa2,0xf3] + +scd $2, -128($sp) +# CHECK: scd $2, -128($sp) # encoding: [0x80,0xff,0xa2,0xf3] + +scd $2, 256($sp) +# CHECK: scd $2, 256($sp) # encoding: [0x00,0x01,0xa2,0xf3] + +scd $2, -257($sp) +# CHECK: scd $2, -257($sp) # encoding: [0xff,0xfe,0xa2,0xf3] + +scd $2, 32767($sp) +# CHECK: scd $2, 32767($sp) # encoding: [0xff,0x7f,0xa2,0xf3] + +scd $2, 32768($sp) +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: scd $2, 32768($1) # encoding: [0x00,0x80,0x22,0xf0] + +scd $2, -32768($sp) +# CHECK: scd $2, -32768($sp) # encoding: [0x00,0x80,0xa2,0xf3] + +scd $2, -32769($sp) +# CHECK: lui $1, 65535 # encoding: [0xff,0xff,0x01,0x3c] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: scd $2, 32767($1) # encoding: [0xff,0x7f,0x22,0xf0] + +scd $2, 655987($sp) +# CHECK: lui $1, 10 # encoding: [0x0a,0x00,0x01,0x3c] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: scd $2, 627($1) # encoding: [0x73,0x02,0x22,0xf0] + +scd $2, -655987($sp) +# CHECK: lui $1, 65526 # encoding: [0xf6,0xff,0x01,0x3c] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: scd $2, 64909($1) # encoding: [0x8d,0xfd,0x22,0xf0]