Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -249,6 +249,9 @@ bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI); + bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, + const MCSubtargetInfo *STI, bool IsLoad); + bool reportParseError(Twine ErrorMsg); bool reportParseError(SMLoc Loc, Twine ErrorMsg); @@ -2213,6 +2216,12 @@ return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; case Mips::ABSMacro: return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; + case Mips::LDMacro: + case Mips::SDMacro: + return expandLoadStoreDMacro(Inst, IDLoc, Out, STI, + Inst.getOpcode() == Mips::LDMacro) + ? MER_Fail + : MER_Success; } } @@ -3819,6 +3828,92 @@ return false; } +static unsigned nextReg(unsigned Reg) { + switch (Reg) { + case Mips::ZERO: return Mips::AT; + case Mips::AT: return Mips::V0; + case Mips::V0: return Mips::V1; + case Mips::V1: return Mips::A0; + case Mips::A0: return Mips::A1; + case Mips::A1: return Mips::A2; + case Mips::A2: return Mips::A3; + case Mips::A3: return Mips::T0; + case Mips::T0: return Mips::T1; + case Mips::T1: return Mips::T2; + case Mips::T2: return Mips::T3; + case Mips::T3: return Mips::T4; + case Mips::T4: return Mips::T5; + case Mips::T5: return Mips::T6; + case Mips::T6: return Mips::T7; + case Mips::T7: return Mips::S0; + case Mips::S0: return Mips::S1; + case Mips::S1: return Mips::S2; + case Mips::S2: return Mips::S3; + case Mips::S3: return Mips::S4; + case Mips::S4: return Mips::S5; + case Mips::S5: return Mips::S6; + case Mips::S6: return Mips::S7; + case Mips::S7: return Mips::T8; + case Mips::T8: return Mips::T9; + case Mips::T9: return Mips::K0; + case Mips::K0: return Mips::K1; + case Mips::K1: return Mips::GP; + case Mips::GP: return Mips::SP; + case Mips::SP: return Mips::FP; + case Mips::FP: return Mips::RA; + case Mips::RA: return Mips::ZERO; + default: return 0; + } + +} + +// Expand 'ld $ offset($reg2)' to 'lw $, offset($reg2); +// lw $>, offset+4($reg2)' +// or expand 'sd $ offset($reg2)' to 'sw $, offset($reg2); +// sw $>, offset+4($reg2)' +// for O32. +bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, + MCStreamer &Out, + const MCSubtargetInfo *STI, + bool IsLoad) { + if (!isABI_O32()) + return true; + + warnIfNoMacro(IDLoc); + + MipsTargetStreamer &TOut = getTargetStreamer(); + unsigned Opcode = IsLoad ? Mips::LW : Mips::SW; + unsigned FirstReg = Inst.getOperand(0).getReg(); + unsigned SecondReg = nextReg(FirstReg); + unsigned BaseReg = Inst.getOperand(1).getReg(); + if (!SecondReg) + return true; + + warnIfRegIndexIsAT(FirstReg, IDLoc); + + assert(Inst.getOperand(2).isImm() && + "Offset for load macro is not immediate!"); + + MCOperand &FirstOffset = Inst.getOperand(2); + signed NextOffset = FirstOffset.getImm() + 4; + MCOperand SecondOffset = MCOperand::createImm(NextOffset); + + if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset)) + return true; + + // For loads, clobber the base register with the second load instead of the + // first if the BaseReg == FirstReg. + if (FirstReg != BaseReg || !IsLoad) { + TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI); + TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI); + } else { + TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI); + TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI); + } + + return false; +} + unsigned MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst, const OperandVector &Operands) { Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -157,6 +157,8 @@ AssemblerPredicate<"FeatureMips3_32r2">; def HasMips3 : Predicate<"Subtarget->hasMips3()">, AssemblerPredicate<"FeatureMips3">; +def NotMips3 : Predicate<"!Subtarget->hasMips3()">, + AssemblerPredicate<"!FeatureMips3">; def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">, AssemblerPredicate<"FeatureMips4_32">; def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">, @@ -242,6 +244,9 @@ // subtractive predicate will hopefully keep us under the 32 predicate // limit long enough to develop an alternative way to handle P1||P2 // predicates. +class ISA_MIPS1_NOT_MIPS3 { + list InsnPredicates = [NotMips3]; +} class ISA_MIPS1_NOT_4_32 { list InsnPredicates = [NotMips4_32]; } @@ -2532,6 +2537,12 @@ def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr), "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6; +def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), + (ins mem_simm16:$addr), "ld $rt, $addr">, + ISA_MIPS1_NOT_MIPS3; +def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), + (ins mem_simm16:$addr), "sd $rt, $addr">, + ISA_MIPS1_NOT_MIPS3; //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// Index: test/MC/Mips/macro-ld-sd.s =================================================================== --- /dev/null +++ test/MC/Mips/macro-ld-sd.s @@ -0,0 +1,24 @@ +# RUN: llvm-mc -triple mips-mti-linux-gnu -show-encoding %s | FileCheck \ +# RUN: --check-prefixes=ALL,32 %s +# RUN: llvm-mc -triple mips64-mti-linux-gnu -show-encoding %s -target-abi n64 \ +# RUN: | FileCheck --check-prefixes=ALL,64 %s +# RUN: llvm-mc -triple mips64-mti-linux-gnu -show-encoding %s -target-abi n32 \ +# RUN: | FileCheck --check-prefixes=ALL,64 %s + +# ALL: .text + ld $8, 0($5) +# 32: lw $8, 0($5) # encoding: [0x8c,0xa8,0x00,0x00] +# 32: lw $9, 4($5) # encoding: [0x8c,0xa9,0x00,0x04] +# 64: ld $8, 0($5) # encoding: [0xdc,0xa8,0x00,0x00] + sd $8, 0($5) +# 32: sw $8, 0($5) # encoding: [0xac,0xa8,0x00,0x00] +# 32: sw $9, 4($5) # encoding: [0xac,0xa9,0x00,0x04] +# 64: sd $8, 0($5) # encoding: [0xfc,0xa8,0x00,0x00] + ld $8, 0($8) +# 32: lw $9, 4($8) # encoding: [0x8d,0x09,0x00,0x04] +# 32: lw $8, 0($8) # encoding: [0x8d,0x08,0x00,0x00] +# 64: ld $8, 0($8) # encoding: [0xdd,0x08,0x00,0x00] + sd $8, 0($8) +# 32: sw $8, 0($8) # encoding: [0xad,0x08,0x00,0x00] +# 32: sw $9, 4($8) # encoding: [0xad,0x09,0x00,0x04] +# 64: sd $8, 0($8) # encoding: [0xfd,0x08,0x00,0x00] Index: test/MC/Mips/mips1/invalid-mips3.s =================================================================== --- test/MC/Mips/mips1/invalid-mips3.s +++ test/MC/Mips/mips1/invalid-mips3.s @@ -54,14 +54,12 @@ floor.l.s $f12,$f5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled floor.w.d $f14,$f11 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled floor.w.s $f8,$f9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled - ld $sp,-28645($s1) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset lld $zero,-14736($ra) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset lwu $s3,-24086($v1) # CHECK: :[[@LINE]]:23: error: expected memory with 12-bit signed offset round.l.d $f12,$f1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled round.l.s $f25,$f5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled round.w.d $f6,$f4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled round.w.s $f27,$f28 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled - sd $12,5835($10) # CHECK: :[[@LINE]]:23: error: expected memory with 16-bit signed offset sqrt.d $f17,$f22 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled sqrt.s $f0,$f1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled teqi $s5,-17504 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips1/invalid-mips4.s =================================================================== --- test/MC/Mips/mips1/invalid-mips4.s +++ test/MC/Mips/mips1/invalid-mips4.s @@ -69,14 +69,12 @@ movz $a1,$s6,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled movz.d $f12,$f29,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled movz.s $f25,$f7,$v1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled - ld $sp,-28645($s1) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset lld $zero,-14736($ra) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset lwu $s3,-24086($v1) # CHECK: :[[@LINE]]:23: error: expected memory with 12-bit signed offset round.l.d $f12,$f1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled round.l.s $f25,$f5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled round.w.d $f6,$f4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled round.w.s $f27,$f28 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled - sd $12,5835($10) # CHECK: :[[@LINE]]:23: error: expected memory with 16-bit signed offset sdxc1 $f11,$10($14) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled sqrt.d $f17,$f22 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled sqrt.s $f0,$f1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips2/invalid-mips3.s =================================================================== --- test/MC/Mips/mips2/invalid-mips3.s +++ test/MC/Mips/mips2/invalid-mips3.s @@ -50,11 +50,9 @@ eret # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled floor.l.d $f26,$f7 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled floor.l.s $f12,$f5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled - ld $sp,-28645($s1) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset lld $zero,-14736($ra) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset lwu $s3,-24086($v1) # CHECK: :[[@LINE]]:24: error: expected memory with 12-bit signed offset round.l.d $f12,$f1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled round.l.s $f25,$f5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled - sd $t0,5835($a6) # CHECK: :[[@LINE]]:24: error: expected memory with 16-bit signed offset trunc.l.d $f23,$f23 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled trunc.l.s $f28,$f31 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips2/invalid-mips4.s =================================================================== --- test/MC/Mips/mips2/invalid-mips4.s +++ test/MC/Mips/mips2/invalid-mips4.s @@ -66,10 +66,8 @@ movz $a1,$s6,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled movz.d $f12,$f29,$9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled movz.s $f25,$f7,$v1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled - ld $sp,-28645($s1) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 16-bit signed offset round.l.d $f12,$f1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled round.l.s $f25,$f5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled - sd $12,5835($10) # CHECK: :[[@LINE]]:23: error: expected memory with 16-bit signed offset sdxc1 $f11,$10($14) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled trunc.l.d $f23,$f23 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled trunc.l.s $f28,$f31 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled