Index: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -245,12 +245,6 @@ void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI, bool IsLoad); - void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, - const MCSubtargetInfo *STI); - - void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, - const MCSubtargetInfo *STI); - bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI); @@ -1326,7 +1320,7 @@ return false; if (!getMemBase()->isGPRAsmReg()) return false; - const unsigned PtrBits = 32; + const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32; if (isa(getMemOff()) || (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff()))) return true; @@ -2143,7 +2137,7 @@ (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { MCOperand &Op = Inst.getOperand(i); if (Op.isImm()) { - int MemOffset = Op.getImm(); + int64_t MemOffset = Op.getImm(); if (MemOffset < -32768 || MemOffset > 32767) { // Offset can't exceed 16bit value. expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad()); @@ -3569,14 +3563,6 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI, bool IsLoad) { - if (IsLoad) - expandLoadInst(Inst, IDLoc, Out, STI); - else - expandStoreInst(Inst, IDLoc, Out, STI); -} - -void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, - const MCSubtargetInfo *STI) { const MCOperand &DstRegOp = Inst.getOperand(0); assert(DstRegOp.isReg() && "expected register operand kind"); const MCOperand &BaseRegOp = Inst.getOperand(1); @@ -3595,7 +3581,7 @@ bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) || (DstRegClassID == Mips::GPR64RegClassID); - if (!IsGPR || (BaseReg == DstReg)) { + if (!IsLoad || !IsGPR || (BaseReg == DstReg)) { // At this point we need AT to perform the expansions // and we exit if it is not available. TmpReg = getATReg(IDLoc); @@ -3604,8 +3590,27 @@ } if (OffsetOp.isImm()) { - TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg, - OffsetOp.getImm(), TmpReg, IDLoc, STI); + int64_t LoOffset = OffsetOp.getImm() & 0xffff; + int64_t HiOffset = OffsetOp.getImm() & ~0xffff; + + // If msb of LoOffset is 1(negative number) we must increment + // HiOffset to account for the sign-extension of the low part. + if (LoOffset & 0x8000) + HiOffset += 0x10000; + + bool IsLargeOffset = HiOffset != 0; + + if (IsLargeOffset) { + bool Is32BitImm = (HiOffset >> 32) == 0; + if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true, + IDLoc, Out, STI)) + return; + } + + if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64) + TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, + BaseReg, IDLoc, STI); + TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, LoOffset, IDLoc, STI); } else { assert(OffsetOp.isExpr() && "expected expression operand kind"); const MCExpr *ExprOffset = OffsetOp.getExpr(); @@ -3613,42 +3618,14 @@ MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext())); MCOperand HiOperand = MCOperand::createExpr( MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext())); - TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand, - LoOperand, TmpReg, IDLoc, STI); - } -} -void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, - const MCSubtargetInfo *STI) { - const MCOperand &SrcRegOp = Inst.getOperand(0); - assert(SrcRegOp.isReg() && "expected register operand kind"); - const MCOperand &BaseRegOp = Inst.getOperand(1); - assert(BaseRegOp.isReg() && "expected register operand kind"); - const MCOperand &OffsetOp = Inst.getOperand(2); - - MipsTargetStreamer &TOut = getTargetStreamer(); - unsigned SrcReg = SrcRegOp.getReg(); - unsigned BaseReg = BaseRegOp.getReg(); - - if (OffsetOp.isImm()) { - TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg, - OffsetOp.getImm(), - [&]() { return getATReg(IDLoc); }, IDLoc, STI); - return; + if (IsLoad) + TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand, + LoOperand, TmpReg, IDLoc, STI); + else + TOut.emitStoreWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand, + LoOperand, TmpReg, IDLoc, STI); } - - unsigned ATReg = getATReg(IDLoc); - if (!ATReg) - return; - - assert(OffsetOp.isExpr() && "expected expression operand kind"); - const MCExpr *ExprOffset = OffsetOp.getExpr(); - MCOperand LoOperand = MCOperand::createExpr( - MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext())); - MCOperand HiOperand = MCOperand::createExpr( - MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext())); - TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand, - LoOperand, ATReg, IDLoc, STI); } bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, Index: llvm/trunk/test/MC/Mips/mips64-expansions.s =================================================================== --- llvm/trunk/test/MC/Mips/mips64-expansions.s +++ llvm/trunk/test/MC/Mips/mips64-expansions.s @@ -270,11 +270,10 @@ # CHECK: lwl $8, 3($1) # encoding: [0x03,0x00,0x28,0x88] # CHECK: lwr $8, 0($1) # encoding: [0x00,0x00,0x28,0x98] -# Test ld/sd/lld with offsets exceed 16-bit size. +# Test lb/sb/ld/sd/lld with offsets exceeding 16-bits in size. ld $4, 0x8000 # CHECK: lui $4, 1 -# CHECK-NEXT: addu $4, $4, $zero # CHECK-NEXT: ld $4, -32768($4) ld $4, 0x20008($3) @@ -282,9 +281,32 @@ # CHECK-NEXT: addu $4, $4, $3 # CHECK-NEXT: ld $4, 8($4) + ld $4,0x100010004 +# CHECK: addiu $4, $zero, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ld $4, 4($4) + + ld $4,0x1800180018004 +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ld $4, -32764($4) + + ld $4,0x1800180018004($3) +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: daddu $4, $4, $3 +# CHECK-NEXT: ld $4, -32764($4) + sd $4, 0x8000 # CHECK: lui $1, 1 -# CHECK-NEXT: addu $1, $1, $zero # CHECK-NEXT: sd $4, -32768($1) sd $4, 0x20008($3) @@ -292,12 +314,155 @@ # CHECK-NEXT: addu $1, $1, $3 # CHECK-NEXT: sd $4, 8($1) + sd $4,0x100010004 +# CHECK: addiu $1, $zero, 1 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: ori $1, $1, 1 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: sd $4, 4($1) + + sd $4,0x1800180018004 +# CHECK: lui $1, 1 +# CHECK-NEXT: ori $1, $1, 32769 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: ori $1, $1, 32770 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: sd $4, -32764($1) + + sd $4,0x1800180018004($3) +# CHECK: lui $1, 1 +# CHECK-NEXT: ori $1, $1, 32769 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: ori $1, $1, 32770 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: daddu $1, $1, $3 +# CHECK-NEXT: sd $4, -32764($1) + lld $4, 0x8000 # CHECK: lui $4, 1 -# CHECK-NEXT: addu $4, $4, $zero # CHECK-NEXT: lld $4, -32768($4) lld $4, 0x20008($3) # CHECK: lui $4, 2 # CHECK-NEXT: addu $4, $4, $3 # CHECK-NEXT: lld $4, 8($4) + + lld $4,0x100010004 +# CHECK: addiu $4, $zero, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: lld $4, 4($4) + + lld $4,0x1800180018004 +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: lld $4, -32764($4) + + lld $4,0x1800180018004($3) +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: daddu $4, $4, $3 +# CHECK-NEXT: lld $4, -32764($4) + + lb $4,0x100010004 +# CHECK: addiu $4, $zero, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: lb $4, 4($4) + + lb $4,0x1800180018004 +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: lb $4, -32764($4) + + lb $4,0x1800180018004($3) +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: daddu $4, $4, $3 +# CHECK-NEXT: lb $4, -32764($4) + + sb $4,0x100010004 +# CHECK: addiu $1, $zero, 1 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: ori $1, $1, 1 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: sb $4, 4($1) + + sb $4,0x1800180018004 +# CHECK: lui $1, 1 +# CHECK-NEXT: ori $1, $1, 32769 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: ori $1, $1, 32770 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: sb $4, -32764($1) + + sb $4,0x1800180018004($3) +# CHECK: lui $1, 1 +# CHECK-NEXT: ori $1, $1, 32769 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: ori $1, $1, 32770 +# CHECK-NEXT: dsll $1, $1, 16 +# CHECK-NEXT: daddu $1, $1, $3 +# CHECK-NEXT: sb $4, -32764($1) + + lh $4,0x100010004 +# CHECK: addiu $4, $zero, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: lh $4, 4($4) + + lh $4,0x1800180018004 +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: lh $4, -32764($4) + + lh $4,0x1800180018004($3) +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: daddu $4, $4, $3 +# CHECK-NEXT: lh $4, -32764($4) + + lhu $4,0x100010004 +# CHECK: addiu $4, $zero, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 1 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: lhu $4, 4($4) + + lhu $4,0x1800180018004 +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: lhu $4, -32764($4) + + lhu $4,0x1800180018004($3) +# CHECK: lui $4, 1 +# CHECK-NEXT: ori $4, $4, 32769 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: ori $4, $4, 32770 +# CHECK-NEXT: dsll $4, $4, 16 +# CHECK-NEXT: daddu $4, $4, $3 +# CHECK-NEXT: lhu $4, -32764($4) Index: llvm/trunk/test/MC/Mips/mips64r5/invalid.s =================================================================== --- llvm/trunk/test/MC/Mips/mips64r5/invalid.s +++ llvm/trunk/test/MC/Mips/mips64r5/invalid.s @@ -20,12 +20,8 @@ dmfc0 $4, $3, 8 # CHECK: :[[@LINE]]:24: error: expected 3-bit unsigned immediate sd $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number lb $32, 8($5) # CHECK: :[[@LINE]]:12: error: invalid register number - lb $4, -2147483649($5) # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset - lb $4, 2147483648($5) # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset lb $4, 8($32) # CHECK: :[[@LINE]]:18: error: invalid register number lbu $32, 8($5) # CHECK: :[[@LINE]]:13: error: invalid register number - lbu $4, -2147483649($5) # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset - lbu $4, 2147483648($5) # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset lbu $4, 8($32) # CHECK: :[[@LINE]]:19: error: invalid register number ldc1 $f32, 300($10) # CHECK: :[[@LINE]]:14: error: invalid operand for instruction ldc1 $f7, -32769($10) # CHECK: :[[@LINE]]:19: error: expected memory with 16-bit signed offset Index: llvm/trunk/test/MC/Mips/mips64r5/valid.s =================================================================== --- llvm/trunk/test/MC/Mips/mips64r5/valid.s +++ llvm/trunk/test/MC/Mips/mips64r5/valid.s @@ -194,20 +194,21 @@ jalr.hb $4, $5 # CHECK: jalr.hb $4, $5 # encoding: [0x00,0xa0,0x24,0x09] l.s $f2, 8($3) # CHECK: lwc1 $f2, 8($3) # encoding: [0xc4,0x62,0x00,0x08] l.d $f2, 8($3) # CHECK: ldc1 $f2, 8($3) # encoding: [0xd4,0x62,0x00,0x08] - lb $24,-14515($10) - lbu $8,30195($v1) - ld $sp,-28645($s1) + lb $24,-2147483649($10) + lbu $24,-2147483649($10) + ld $sp,-2147483649($s1) ldc1 $f11,16391($s0) ldc2 $8,-21181($at) # CHECK: ldc2 $8, -21181($1) # encoding: [0xd8,0x28,0xad,0x43] ldl $24,-4167($24) ldr $14,-30358($s4) ldxc1 $f8,$s7($15) - lh $11,-8556($s5) - lhu $s3,-22851($v0) + lh $11,-2147483649($s5) + lhu $s3,-2147483649($v0) li $at,-29773 li $zero,-29889 ll $v0,-7321($s2) # CHECK: ll $2, -7321($18) # encoding: [0xc2,0x42,0xe3,0x67] lld $zero,-14736($ra) # CHECK: lld $zero, -14736($ra) # encoding: [0xd3,0xe0,0xc6,0x70] + lld $24,-2147483649($10) luxc1 $f19,$s6($s5) lw $8,5674($a1) lwc1 $f16,10225($k0) Index: llvm/trunk/test/MC/Mips/mips64r6/invalid.s =================================================================== --- llvm/trunk/test/MC/Mips/mips64r6/invalid.s +++ llvm/trunk/test/MC/Mips/mips64r6/invalid.s @@ -60,12 +60,8 @@ lhe $4, 8($33) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number lhu $4, 8($35) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number lhue $4, 8($37) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number - lh $2, -2147483649($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset - lh $2, 2147483648($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset lhe $4, -512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction lhe $4, 512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction - lhu $4, -2147483649($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset - lhu $4, 2147483648($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset lhue $4, -512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction lhue $4, 512($2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction // FIXME: Following tests are temporarily disabled, until "PredicateControl not in hierarchy" problem is resolved @@ -178,14 +174,8 @@ dmtc0 $4, $3, 8 # CHECK: :[[@LINE]]:24: error: expected 3-bit unsigned immediate dmfc0 $4, $3, -1 # CHECK: :[[@LINE]]:24: error: expected 3-bit unsigned immediate dmfc0 $4, $3, 8 # CHECK: :[[@LINE]]:24: error: expected 3-bit unsigned immediate - ld $2, 2147483648($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset - ld $2, -2147483649($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset ld $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number - lld $2, -2147483649($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset - lld $2, 2147483648($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset - sd $2, -2147483649($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset lld $32, 4096($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number - sd $2, 2147483648($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 32-bit signed offset sd $32, 65536($32) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number dsrl $2, $4, 64 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 6-bit unsigned immediate dsrl $2, $4, -2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 6-bit unsigned immediate @@ -195,12 +185,8 @@ dsrlv $2, $4, 2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction dsrlv $32, $32, $32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register number lb $32, 8($5) # CHECK: :[[@LINE]]:12: error: invalid register number - lb $4, -2147483649($5) # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset - lb $4, 2147483648($5) # CHECK: :[[@LINE]]:16: error: expected memory with 32-bit signed offset lb $4, 8($32) # CHECK: :[[@LINE]]:18: error: invalid register number lbu $32, 8($5) # CHECK: :[[@LINE]]:13: error: invalid register number - lbu $4, -2147483649($5) # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset - lbu $4, 2147483648($5) # CHECK: :[[@LINE]]:17: error: expected memory with 32-bit signed offset lbu $4, 8($32) # CHECK: :[[@LINE]]:19: error: invalid register number ldc1 $f32, 300($10) # CHECK: :[[@LINE]]:14: error: invalid operand for instruction ldc1 $f7, -32769($10) # CHECK: :[[@LINE]]:19: error: expected memory with 16-bit signed offset