Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -223,6 +223,9 @@ bool expandUlw(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions); + + bool expandLlSc(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions, bool IsMips64); bool expandRotation(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions); @@ -1497,6 +1500,25 @@ 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 emitRRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, + int16_t Imm, SMLoc IDLoc, SmallVectorImpl &Instructions) { + emitRRRX(Opcode, Reg0, Reg1, Reg2, MCOperand::createImm(Imm), IDLoc, + Instructions); +} + void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, SMLoc IDLoc, SmallVectorImpl &Instructions) { if (ShiftAmount >= 32) { @@ -2043,6 +2065,13 @@ return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success; case Mips::Ulw: return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success; + case Mips::LLDMacro: + case Mips::SCDMacro: + return expandLlSc(Inst, IDLoc, Instructions, true) ? MER_Fail : MER_Success; + case Mips::LLMacro: + case Mips::SCMacro: + return expandLlSc(Inst, IDLoc, Instructions, false) ? MER_Fail + : MER_Success; case Mips::NORImm: return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success; @@ -3179,6 +3208,69 @@ return false; } +bool MipsAsmParser::expandLlSc(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl &Instructions, + bool IsMips64) { + + assert(Inst.getNumOperands() == 3 && "Invalid operand count"); + assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && + Inst.getOperand(2).isImm() && "Invalid instruction operand."); + + unsigned DstReg = Inst.getOperand(0).getReg(); + unsigned SrcReg = Inst.getOperand(1).getReg(); + int64_t OffsetValue = Inst.getOperand(2).getImm(); + + unsigned Opcode = Inst.getOpcode(); + + unsigned ATReg = getATReg(IDLoc); + if (!ATReg) + return true; + + bool isLL = Opcode == Mips::LLMacro || Opcode == Mips::LLDMacro; + bool isSC = Opcode == Mips::SCMacro || Opcode == Mips::SCDMacro; + + unsigned LLR6op = IsMips64 ? Mips::LLD_R6 : Mips::LL_R6; + unsigned SCR6op = IsMips64 ? Mips::SCD_R6 : Mips::SC_R6; + + unsigned TmpReg = isLL ? DstReg : ATReg; + + // If 9 bit offset + if (OffsetValue > -257 && OffsetValue < 256) { + if (isLL) { + emitRRI(LLR6op, DstReg, SrcReg, OffsetValue, IDLoc, Instructions); + return false; + } else if (isSC) { + emitRRRI(SCR6op, DstReg, DstReg, SrcReg, OffsetValue, IDLoc, + Instructions); + return false; + } + } + // If 16 bit offset + else if (OffsetValue > -32769 && OffsetValue < 32768) { + emitRRI(Mips::ADDiu, TmpReg, SrcReg, OffsetValue, IDLoc, Instructions); + if (isLL) { + emitRRI(LLR6op, DstReg, TmpReg, 0, IDLoc, Instructions); + return false; + } else if (isSC) { + emitRRRI(SCR6op, DstReg, DstReg, TmpReg, 0, IDLoc, Instructions); + return false; + } + } else { + bool Is32Bit = isInt<32>(OffsetValue) || isUInt<32>(OffsetValue); + loadImmediate(OffsetValue, TmpReg, Mips::NoRegister, Is32Bit, false, IDLoc, + Instructions); + emitRRR(Mips::ADDu, TmpReg, TmpReg, SrcReg, IDLoc, Instructions); + if (isLL) { + emitRRI(LLR6op, DstReg, TmpReg, 0, IDLoc, Instructions); + return false; + } else if (isSC) { + emitRRRI(SCR6op, DstReg, DstReg, TmpReg, 0, IDLoc, Instructions); + return false; + } + } + return true; +} + bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl &Instructions) { Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -845,3 +845,9 @@ def : MipsPat<(select i32:$cond, immz, i32:$f), (SELEQZ i32:$f, i32:$cond)>, ISA_MIPS32R6; + +def SCMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rt, mem:$addr), + "sc\t$rt, $addr">, ISA_MIPS32R6; + +def LLMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), + "ll\t$rt, $addr">, ISA_MIPS32R6; Index: lib/Target/Mips/Mips64r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64r6InstrInfo.td +++ lib/Target/Mips/Mips64r6InstrInfo.td @@ -217,3 +217,9 @@ def : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i64:$f), (SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>, ISA_MIPS64R6; + +def SCDMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rt, mem:$addr), + "scd\t$rt, $addr">, ISA_MIPS64R6; + +def LLDMacro : MipsAsmPseudoInst<(outs GPR64Opnd:$rt), (ins mem:$addr), + "lld\t$rt, $addr">, ISA_MIPS64R6; Index: test/MC/Mips/ll_r6.s =================================================================== --- test/MC/Mips/ll_r6.s +++ test/MC/Mips/ll_r6.s @@ -0,0 +1,46 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r6 -show-encoding | FileCheck %s + +ll $2, 128($sp) +# CHECK: ll $2, 128($sp) # encoding: [0x36,0x40,0xa2,0x7f] + +ll $2, -128($sp) +# CHECK: ll $2, -128($sp) # encoding: [0x36,0xc0,0xa2,0x7f] + +ll $2, 256($sp) +# CHECK: addiu $2, $sp, 256 # encoding: [0x00,0x01,0xa2,0x27] +# CHECK: ll $2, 0($2) # encoding: [0x36,0x00,0x42,0x7c] + +ll $2, -257($sp) +# CHECK: addiu $2, $sp, -257 # encoding: [0xff,0xfe,0xa2,0x27] +# CHECK: ll $2, 0($2) # encoding: [0x36,0x00,0x42,0x7c] + +ll $2, 32767($sp) +# CHECK: addiu $2, $sp, 32767 # encoding: [0xff,0x7f,0xa2,0x27] +# CHECK: ll $2, 0($2) # encoding: [0x36,0x00,0x42,0x7c] + +ll $2, 32768($sp) +# CHECK: ori $2, $zero, 32768 # encoding: [0x00,0x80,0x02,0x34] +# CHECK: addu $2, $2, $sp # encoding: [0x21,0x10,0x5d,0x00] +# CHECK: ll $2, 0($2) # encoding: [0x36,0x00,0x42,0x7c] + +ll $2, -32768($sp) +# CHECK: addiu $2, $sp, -32768 # encoding: [0x00,0x80,0xa2,0x27] +# CHECK: ll $2, 0($2) # encoding: [0x36,0x00,0x42,0x7c] + +ll $2, -32769($sp) +# CHECK: lui $2, 65535 # encoding: [0xff,0xff,0x02,0x3c] +# CHECK: ori $2, $2, 32767 # encoding: [0xff,0x7f,0x42,0x34] +# CHECK: addu $2, $2, $sp # encoding: [0x21,0x10,0x5d,0x00] +# CHECK: ll $2, 0($2) # encoding: [0x36,0x00,0x42,0x7c] + +ll $2, 655987($sp) +# CHECK: lui $2, 10 # encoding: [0x0a,0x00,0x02,0x3c] +# CHECK: ori $2, $2, 627 # encoding: [0x73,0x02,0x42,0x34] +# CHECK: addu $2, $2, $sp # encoding: [0x21,0x10,0x5d,0x00] +# CHECK: ll $2, 0($2) # encoding: [0x36,0x00,0x42,0x7c] + +ll $2, -655987($sp) +# CHECK: lui $2, 65525 # encoding: [0xf5,0xff,0x02,0x3c] +# CHECK: ori $2, $2, 64909 # encoding: [0x8d,0xfd,0x42,0x34] +# CHECK: addu $2, $2, $sp # encoding: [0x21,0x10,0x5d,0x00] +# CHECK: ll $2, 0($2) # encoding: [0x36,0x00,0x42,0x7c] Index: test/MC/Mips/lld_r6.s =================================================================== --- test/MC/Mips/lld_r6.s +++ test/MC/Mips/lld_r6.s @@ -0,0 +1,53 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips64r6 -show-encoding | FileCheck %s + +lld $2, 128($sp) +# CHECK: lld $2, 128($sp) # encoding: [0x37,0x40,0xa2,0x7f] + +lld $2, -128($sp) +# CHECK: lld $2, -128($sp) # encoding: [0x37,0xc0,0xa2,0x7f] + +lld $2, 255($sp) +# CHECK: lld $2, 255($sp) # encoding: [0xb7,0x7f,0xa2,0x7f] + +lld $2, 256($sp) +# CHECK: addiu $2, $sp, 256 # encoding: [0x00,0x01,0xa2,0x27] +# CHECK: lld $2, 0($2) # encoding: [0x37,0x00,0x42,0x7c] + +lld $2, -256($sp) +# CHECK: lld $2, -256($sp) # encoding: [0x37,0x80,0xa2,0x7f] + +lld $2, -257($sp) +# CHECK: addiu $2, $sp, -257 # encoding: [0xff,0xfe,0xa2,0x27] +# CHECK: lld $2, 0($2) # encoding: [0x37,0x00,0x42,0x7c] + + +lld $2, 32767($sp) +# CHECK: addiu $2, $sp, 32767 # encoding: [0xff,0x7f,0xa2,0x27] +# CHECK: lld $2, 0($2) # encoding: [0x37,0x00,0x42,0x7c] + +lld $2, 32768($sp) +# CHECK: ori $2, $zero, 32768 # encoding: [0x00,0x80,0x02,0x34] +# CHECK: addu $2, $2, $sp # encoding: [0x21,0x10,0x5d,0x00] +# CHECK: lld $2, 0($2) # encoding: [0x37,0x00,0x42,0x7c] + +lld $2, -32768($sp) +# CHECK: addiu $2, $sp, -32768 # encoding: [0x00,0x80,0xa2,0x27] +# CHECK: lld $2, 0($2) # encoding: [0x37,0x00,0x42,0x7c] + +lld $2, -32769($sp) +# CHECK: lui $2, 65535 # encoding: [0xff,0xff,0x02,0x3c] +# CHECK: ori $2, $2, 32767 # encoding: [0xff,0x7f,0x42,0x34] +# CHECK: addu $2, $2, $sp # encoding: [0x21,0x10,0x5d,0x00] +# CHECK: lld $2, 0($2) # encoding: [0x37,0x00,0x42,0x7c] + +lld $2, 655987($sp) +# CHECK: lui $2, 10 # encoding: [0x0a,0x00,0x02,0x3c] +# CHECK: ori $2, $2, 627 # encoding: [0x73,0x02,0x42,0x34] +# CHECK: addu $2, $2, $sp # encoding: [0x21,0x10,0x5d,0x00] +# CHECK: lld $2, 0($2) # encoding: [0x37,0x00,0x42,0x7c] + +lld $2, -655987($sp) +# CHECK: lui $2, 65525 # encoding: [0xf5,0xff,0x02,0x3c] +# CHECK: ori $2, $2, 64909 # encoding: [0x8d,0xfd,0x42,0x34] +# CHECK: addu $2, $2, $sp # encoding: [0x21,0x10,0x5d,0x00] +# CHECK: lld $2, 0($2) # encoding: [0x37,0x00,0x42,0x7c] Index: test/MC/Mips/sc_r6.s =================================================================== --- test/MC/Mips/sc_r6.s +++ test/MC/Mips/sc_r6.s @@ -0,0 +1,46 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r6 -show-encoding | FileCheck %s + +sc $2, 128($sp) +# CHECK: sc $2, 128($sp) # encoding: [0x26,0x40,0xa2,0x7f] + +sc $2, -128($sp) +# CHECK: sc $2, -128($sp) # encoding: [0x26,0xc0,0xa2,0x7f] + +sc $2, 256($sp) +# CHECK: addiu $1, $sp, 256 # encoding: [0x00,0x01,0xa1,0x27] +# CHECK: sc $2, 0($1) # encoding: [0x26,0x00,0x22,0x7c] + +sc $2, -257($sp) +# CHECK: addiu $1, $sp, -257 # encoding: [0xff,0xfe,0xa1,0x27] +# CHECK: sc $2, 0($1) # encoding: [0x26,0x00,0x22,0x7c] + +sc $2, 32767($sp) +# CHECK: addiu $1, $sp, 32767 # encoding: [0xff,0x7f,0xa1,0x27] +# CHECK: sc $2, 0($1) # encoding: [0x26,0x00,0x22,0x7c] + +sc $2, 32768($sp) +# CHECK: ori $1, $zero, 32768 # encoding: [0x00,0x80,0x01,0x34] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: sc $2, 0($1) # encoding: [0x26,0x00,0x22,0x7c] + +sc $2, -32768($sp) +# CHECK: addiu $1, $sp, -32768 # encoding: [0x00,0x80,0xa1,0x27] +# CHECK: sc $2, 0($1) # encoding: [0x26,0x00,0x22,0x7c] + +sc $2, -32769($sp) +# CHECK: lui $1, 65535 # encoding: [0xff,0xff,0x01,0x3c] +# CHECK: ori $1, $1, 32767 # encoding: [0xff,0x7f,0x21,0x34] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: sc $2, 0($1) # encoding: [0x26,0x00,0x22,0x7c] + +sc $2, 655987($sp) +# CHECK: lui $1, 10 # encoding: [0x0a,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 627 # encoding: [0x73,0x02,0x21,0x34] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: sc $2, 0($1) # encoding: [0x26,0x00,0x22,0x7c] + +sc $2, -655987($sp) +# CHECK: lui $1, 65525 # encoding: [0xf5,0xff,0x01,0x3c] +# CHECK: ori $1, $1, 64909 # encoding: [0x8d,0xfd,0x21,0x34] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: sc $2, 0($1) # encoding: [0x26,0x00,0x22,0x7c] Index: test/MC/Mips/scd_r6.s =================================================================== --- test/MC/Mips/scd_r6.s +++ test/MC/Mips/scd_r6.s @@ -0,0 +1,52 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips64r6 -show-encoding | FileCheck %s + +scd $2, 128($sp) +# CHECK: scd $2, 128($sp) # encoding: [0x27,0x40,0xa2,0x7f] + +scd $2, -128($sp) +# CHECK: scd $2, -128($sp) # encoding: [0x27,0xc0,0xa2,0x7f] + +scd $2, 255($sp) +# CHECK: scd $2, 255($sp) # encoding: [0xa7,0x7f,0xa2,0x7f] + +scd $2, 256($sp) +# CHECK: addiu $1, $sp, 256 # encoding: [0x00,0x01,0xa1,0x27] +# CHECK: scd $2, 0($1) # encoding: [0x27,0x00,0x22,0x7c] + +scd $2, -256($sp) +# CHECK: scd $2, -256($sp) # encoding: [0x27,0x80,0xa2,0x7f] + +scd $2, -257($sp) +# CHECK: addiu $1, $sp, -257 # encoding: [0xff,0xfe,0xa1,0x27] +# CHECK: scd $2, 0($1) # encoding: [0x27,0x00,0x22,0x7c] + +scd $2, 32767($sp) +# CHECK: addiu $1, $sp, 32767 # encoding: [0xff,0x7f,0xa1,0x27] +# CHECK: scd $2, 0($1) # encoding: [0x27,0x00,0x22,0x7c] + +scd $2, 32768($sp) +# CHECK: ori $1, $zero, 32768 # encoding: [0x00,0x80,0x01,0x34] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: scd $2, 0($1) # encoding: [0x27,0x00,0x22,0x7c] + +scd $2, -32768($sp) +# CHECK: addiu $1, $sp, -32768 # encoding: [0x00,0x80,0xa1,0x27] +# CHECK: scd $2, 0($1) # encoding: [0x27,0x00,0x22,0x7c] + +scd $2, -32769($sp) +# CHECK: lui $1, 65535 # encoding: [0xff,0xff,0x01,0x3c] +# CHECK: ori $1, $1, 32767 # encoding: [0xff,0x7f,0x21,0x34] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: scd $2, 0($1) # encoding: [0x27,0x00,0x22,0x7c] + +scd $2, 655987($sp) +# CHECK: lui $1, 10 # encoding: [0x0a,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 627 # encoding: [0x73,0x02,0x21,0x34] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: scd $2, 0($1) # encoding: [0x27,0x00,0x22,0x7c] + +scd $2, -655987($sp) +# CHECK: lui $1, 65525 # encoding: [0xf5,0xff,0x01,0x3c] +# CHECK: ori $1, $1, 64909 # encoding: [0x8d,0xfd,0x21,0x34] +# CHECK: addu $1, $1, $sp # encoding: [0x21,0x08,0x3d,0x00] +# CHECK: scd $2, 0($1) # encoding: [0x27,0x00,0x22,0x7c]