Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -837,7 +837,9 @@ void addMemOperands(MCInst &Inst, unsigned N) const { assert(N == 2 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg())); + Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit() + ? getMemBase()->getGPR64Reg() + : getMemBase()->getGPR32Reg())); const MCExpr *Expr = getMemOff(); addExpr(Inst, Expr); @@ -1619,7 +1621,9 @@ case Mips::LoadImm32: case Mips::LoadImm64: case Mips::LoadAddrImm32: + case Mips::LoadAddrImm64: case Mips::LoadAddrReg32: + case Mips::LoadAddrReg64: case Mips::B_MM_Pseudo: case Mips::LWM_MM: case Mips::SWM_MM: @@ -1651,8 +1655,12 @@ return expandLoadImm(Inst, false, IDLoc, Instructions); case Mips::LoadAddrImm32: return expandLoadAddressImm(Inst, true, IDLoc, Instructions); + case Mips::LoadAddrImm64: + return expandLoadAddressImm(Inst, false, IDLoc, Instructions); case Mips::LoadAddrReg32: return expandLoadAddressReg(Inst, true, IDLoc, Instructions); + case Mips::LoadAddrReg64: + return expandLoadAddressReg(Inst, false, IDLoc, Instructions); case Mips::B_MM_Pseudo: return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions); case Mips::SWM_MM: @@ -1991,9 +1999,29 @@ SMLoc IDLoc, SmallVectorImpl &Instructions) { warnIfNoMacro(IDLoc); + // The following describes the GAS behaviour of (D)LA that we're trying to + // emulate. Note that (D)LA behave the same on N32 and O32. + // + // if LA && O32 && .set mips32 then do the 32-bit expansion + // if LA && O32 && .set mips64 then do the 32-bit expansion + // + // if LA && N64 && .set mips32 then do the 32-bit expansion and warn + // if LA && N64 && .set mips64 then do the 64-bit expansion and warn + // + // if DLA && O32 && .set mips32 then error + // if DLA && O32 && .set mips64 then do the 32-bit expansion + // + // if DLA && N64 && .set mips32 then error + // if DLA && N64 && .set mips64 then do the 64-bit expansion + if (Is32BitSym && isABI_N64()) Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol"); + if (!Is32BitSym && !isGP64bit()) { + Error(IDLoc, "instruction requires a 64-bit architecture"); + return true; + } + MCInst tmpInst; const MCSymbolRefExpr *Symbol = cast(SymExpr); const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create( @@ -2003,55 +2031,111 @@ bool UseSrcReg = SrcReg != Mips::NoRegister; - unsigned TmpReg = DstReg; - if (UseSrcReg && (DstReg == SrcReg)) { - // At this point we need AT to perform the expansions and we exit if it is - // not available. + // This is the 64-bit symbol address expansion. + if (isABI_N64() && isGP64bit()) { + // We always need AT for the 64-bit expansion. + // If it is not available we exit. unsigned ATReg = getATReg(IDLoc); if (!ATReg) return true; - TmpReg = ATReg; - } - if (!Is32BitSym) { - // If it's a 64-bit architecture, expand to: - // la d,sym => lui d,highest(sym) - // ori d,d,higher(sym) - // dsll d,d,16 - // ori d,d,hi16(sym) - // dsll d,d,16 - // ori d,d,lo16(sym) const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create( &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext()); const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create( &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext()); + if (UseSrcReg && (DstReg == SrcReg)) { + // If $rs is the same as $rd: + // (d)la $rd, sym($rd) => lui $at, %highest(sym) + // ori $at, $at, %higher(sym) + // dsll $at, $at, 16 + // ori $at, $at, %hi(sym) + // dsll $at, $at, 16 + // ori $at, $at, %lo(sym) + // daddu $rd, $at, $rd + tmpInst.setOpcode(Mips::LUi); + tmpInst.addOperand(MCOperand::createReg(ATReg)); + tmpInst.addOperand(MCOperand::createExpr(HighestExpr)); + Instructions.push_back(tmpInst); + + createLShiftOri<0>(MCOperand::createExpr(HigherExpr), ATReg, SMLoc(), + Instructions); + createLShiftOri<16>(MCOperand::createExpr(HiExpr), ATReg, SMLoc(), + Instructions); + createLShiftOri<16>(MCOperand::createExpr(LoExpr), ATReg, SMLoc(), + Instructions); + + // Generate the "daddu $rd, $at, $rd". + createAddu(DstReg, ATReg, SrcReg, true, Instructions); + return false; + } + // Otherwise, if the $rs is different from $rd or if $rs isn't specified: + // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym) + // lui $at, %hi(sym) + // ori $rd, $rd, %higher(sym) + // ori $at, $at, %lo(sym) + // dsll32 $rd, $rd, 0 + // daddu $rd, $rd, $at + // (daddu $rd, $rd, $rs) tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(TmpReg)); + tmpInst.addOperand(MCOperand::createReg(DstReg)); tmpInst.addOperand(MCOperand::createExpr(HighestExpr)); Instructions.push_back(tmpInst); - createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(), - Instructions); - createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(), - Instructions); - createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(), - Instructions); - } else { - // Otherwise, expand to: - // la d,sym => lui d,hi16(sym) - // ori d,d,lo16(sym) + tmpInst.clear(); tmpInst.setOpcode(Mips::LUi); - tmpInst.addOperand(MCOperand::createReg(TmpReg)); + tmpInst.addOperand(MCOperand::createReg(ATReg)); tmpInst.addOperand(MCOperand::createExpr(HiExpr)); Instructions.push_back(tmpInst); - createLShiftOri<0>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(), + createLShiftOri<0>(MCOperand::createExpr(HigherExpr), DstReg, SMLoc(), + Instructions); + + createLShiftOri<0>(MCOperand::createExpr(LoExpr), ATReg, SMLoc(), Instructions); + + // Generate the "dsll32 $rd, $rd, 0". + // FIXME: Separate shift generation from ORi generation. + createLShiftOri<32>(0, DstReg, SMLoc(), Instructions); + + // Generate the "daddu $rd, $rd, $at". + createAddu(DstReg, DstReg, ATReg, true, Instructions); + + // Generate the "daddu $rd, $rd, $rs", if necessary. + if (UseSrcReg) + createAddu(DstReg, DstReg, SrcReg, true, Instructions); + + return false; } + // And now, the 32-bit symbol address expansion: + // If $rs is the same as $rd: + // (d)la $rd, sym($rd) => lui $at, %hi(sym) + // ori $at, $at, %lo(sym) + // addu $rd, $at, $rd + // Otherwise, if the $rs is different from $rd or if $rs isn't specified: + // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym) + // ori $rd, $rd, %lo(sym) + // (addu $rd, $rd, $rs) + unsigned TmpReg = DstReg; + if (UseSrcReg && (DstReg == SrcReg)) { + // If $rs is the same as $rd, we need to use AT. + // If it is not available we exit. + unsigned ATReg = getATReg(IDLoc); + if (!ATReg) + return true; + TmpReg = ATReg; + } + + tmpInst.setOpcode(Mips::LUi); + tmpInst.addOperand(MCOperand::createReg(TmpReg)); + tmpInst.addOperand(MCOperand::createExpr(HiExpr)); + Instructions.push_back(tmpInst); + + createLShiftOri<0>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(), + Instructions); if (UseSrcReg) - createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions); + createAddu(DstReg, TmpReg, SrcReg, false, Instructions); return false; } @@ -3042,7 +3126,7 @@ const AsmToken &Tok = Parser.getTok(); // Get the next token. if (Tok.isNot(AsmToken::LParen)) { MipsOperand &Mnemonic = static_cast(*Operands[0]); - if (Mnemonic.getToken() == "la") { + if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") { SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -633,3 +633,8 @@ MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm64), !strconcat(instr_asm, "\t$rt, $imm64")> ; def LoadImm64 : LoadImmediate64<"dli", imm64, GPR64Opnd>; + +def LoadAddrReg64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rt), (ins mem:$addr), + "dla\t$rt, $addr">; +def LoadAddrImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rt), (ins imm64:$imm64), + "dla\t$rt, $imm64">; Index: test/MC/Mips/mips-expansions-bad.s =================================================================== --- test/MC/Mips/mips-expansions-bad.s +++ test/MC/Mips/mips-expansions-bad.s @@ -1,28 +1,69 @@ # RUN: not llvm-mc %s -arch=mips -mcpu=mips32r2 2>%t1 # RUN: FileCheck %s < %t1 --check-prefix=32-BIT -# RUN: not llvm-mc %s -arch=mips64 -mcpu=mips64 -target-abi n32 2>&1 | \ -# RUN: FileCheck %s --check-prefix=64-BIT --check-prefix=N32-ONLY # RUN: not llvm-mc %s -arch=mips64 -mcpu=mips64 -target-abi n64 2>&1 | \ -# RUN: FileCheck %s --check-prefix=64-BIT --check-prefix=N64-ONLY +# RUN: FileCheck %s --check-prefix=64-BIT .text li $5, 0x100000000 # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 32-bit immediate + .set push + .set mips32 + la $8, 20 + # 64-BIT-FIXME: :[[@LINE-1]]:3: warning: instruction loads a 64-bit address + la $8, 20($8) + # 64-BIT-FIXME: :[[@LINE-1]]:3: warning: instruction loads a 64-bit address la $5, 0x100000000 # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate - # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 32-bit immediate + # 64-BIT-FIXME: :[[@LINE-2]]:3: warning: instruction loads a 64-bit address + # 64-BIT-FIXME: :[[@LINE-3]]:3: error: instruction requires a 32-bit immediate la $5, 0x100000000($6) # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate - # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 32-bit immediate + # 64-BIT-FIXME: :[[@LINE-2]]:3: warning: instruction loads a 64-bit address + # 64-BIT-FIXME: :[[@LINE-3]]:3: error: instruction requires a 32-bit immediate + la $5, symbol + # 64-BIT: :[[@LINE-1]]:3: warning: instruction loads the 32-bit address of a 64-bit symbol + .set mips64 + la $8, 20 + # 64-BIT-FIXME: :[[@LINE-1]]:3: warning: instruction loads a 64-bit address + la $8, 20($8) + # 64-BIT-FIXME: :[[@LINE-1]]:3: warning: instruction loads a 64-bit address + la $5, 0x100000000 + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate + # 64-BIT-FIXME: :[[@LINE-2]]:3: warning: instruction loads a 64-bit address + la $5, 0x100000000($6) + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate + # 64-BIT-FIXME: :[[@LINE-2]]:3: warning: instruction loads a 64-bit address la $5, symbol - # N64-ONLY: :[[@LINE-1]]:3: warning: instruction loads the 32-bit address of a 64-bit symbol - # N32-ONLY-NOT: :[[@LINE-2]]:3: warning: instruction loads the 32-bit address of a 64-bit symbol - # 64-BIT: lui $5, %hi(symbol) - # 64-BIT: ori $5, $5, %lo(symbol) + # 64-BIT: :[[@LINE-1]]:3: warning: instruction loads the 32-bit address of a 64-bit symbol + .set pop + dli $5, 1 # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 64-bit architecture bne $2, 0x100010001, 1332 # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate beq $2, 0x100010001, 1332 # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate + .set push + .set mips32 + dla $8, 20 + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 64-bit architecture + # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 64-bit architecture + dla $8, 20($8) + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 64-bit architecture + # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 64-bit architecture + dla $5, 0x100000000 + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 64-bit architecture + # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 64-bit architecture + dla $5, 0x100000000($6) + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 64-bit architecture + # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 64-bit architecture + dla $5, symbol + # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 64-bit architecture + # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 64-bit architecture + .set mips64 + dla $5, 0x100000000 + # 32-BIT-FIXME: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate + dla $5, 0x100000000($6) + # 32-BIT-FIXME: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate + .set pop Index: test/MC/Mips/mips-expansions.s =================================================================== --- test/MC/Mips/mips-expansions.s +++ test/MC/Mips/mips-expansions.s @@ -62,6 +62,24 @@ # CHECK: ori $1, $1, 2 # encoding: [0x02,0x00,0x21,0x34] # CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00] +# Test la and dla with a 32-bit architecture at the .module-level and +# a 64-bit architecture at the .set-level: + .set push + .set mips64 + la $8, symbol($9) +# CHECK: lui $8, %hi(symbol) # encoding: [A,A,0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %lo(symbol) # encoding: [A,A,0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $8, $9 # encoding: [0x21,0x40,0x09,0x01] + dla $8, symbol($9) +# CHECK: lui $8, %hi(symbol) # encoding: [A,A,0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %lo(symbol) # encoding: [A,A,0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: addu $8, $8, $9 # encoding: [0x21,0x40,0x09,0x01] + .set pop + # LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst(): .set noat lw $10, symbol($4) Index: test/MC/Mips/mips64-expansions.s =================================================================== --- test/MC/Mips/mips64-expansions.s +++ test/MC/Mips/mips64-expansions.s @@ -271,3 +271,175 @@ # CHECK: ori $1, $1, 65535 # encoding: [0xff,0xff,0x21,0x34] # CHECK: beq $2, $1, 1332 # encoding: [0x4d,0x01,0x41,0x10] # CHECK: nop # encoding: [0x00,0x00,0x00,0x00] + +# Test dla: +# Loading an address from an immediate. + dla $8, 12345 +# CHECK: ori $8, $zero, 12345 # encoding: [0x39,0x30,0x08,0x34] + dla $8, -2345 +# CHECK: addiu $8, $zero, -2345 # encoding: [0xd7,0xf6,0x08,0x24] + +# Loading an address from an immediate through a source register. + dla $8, 20($9) +# CHECK: ori $8, $9, 20 # encoding: [0x14,0x00,0x28,0x35] + dla $8, 65538($9) +# CHECK: lui $8, 1 # encoding: [0x01,0x00,0x08,0x3c] +# CHECK: ori $8, $8, 2 # encoding: [0x02,0x00,0x08,0x35] +# CHECK: daddu $8, $8, $9 # encoding: [0x2d,0x40,0x09,0x01] + dla $8, 0x100010001($9) +# CHECK: lui $8, 1 # encoding: [0x01,0x00,0x08,0x3c] +# CHECK: ori $8, $8, 1 # encoding: [0x01,0x00,0x08,0x35] +# CHECK: dsll $8, $8, 16 # encoding: [0x38,0x44,0x08,0x00] +# CHECK: ori $8, $8, 1 # encoding: [0x01,0x00,0x08,0x35] +# CHECK: daddu $8, $8, $9 # encoding: [0x2d,0x40,0x09,0x01] + dla $8, 0x1000100010001($9) +# CHECK: lui $8, 1 # encoding: [0x01,0x00,0x08,0x3c] +# CHECK: ori $8, $8, 1 # encoding: [0x01,0x00,0x08,0x35] +# CHECK: dsll $8, $8, 16 # encoding: [0x38,0x44,0x08,0x00] +# CHECK: ori $8, $8, 1 # encoding: [0x01,0x00,0x08,0x35] +# CHECK: dsll $8, $8, 16 # encoding: [0x38,0x44,0x08,0x00] +# CHECK: ori $8, $8, 1 # encoding: [0x01,0x00,0x08,0x35] +# CHECK: daddu $8, $8, $9 # encoding: [0x2d,0x40,0x09,0x01] + +# Loading the address of a symbol. + dla $8, symbol +# CHECK: lui $8, %highest(symbol) # encoding: [A,A,0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHEST, kind: fixup_Mips_HIGHEST +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %higher(symbol) # encoding: [A,A,0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHER, kind: fixup_Mips_HIGHER +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: dsll32 $8, $8, 0 # encoding: [0x3c,0x40,0x08,0x00] +# CHECK: daddu $8, $8, $1 # encoding: [0x2d,0x40,0x01,0x01] + +# Loading the address of a symbol through a source register. + dla $8, symbol($9) +# CHECK: lui $8, %highest(symbol) # encoding: [A,A,0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHEST, kind: fixup_Mips_HIGHEST +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %higher(symbol) # encoding: [A,A,0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHER, kind: fixup_Mips_HIGHER +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: dsll32 $8, $8, 0 # encoding: [0x3c,0x40,0x08,0x00] +# CHECK: daddu $8, $8, $1 # encoding: [0x2d,0x40,0x01,0x01] +# CHECK: daddu $8, $8, $9 # encoding: [0x2d,0x40,0x09,0x01] + +# When the source and destination registers are the same. + dla $8, 20($8) +# CHECK: ori $8, $8, 20 # encoding: [0x14,0x00,0x08,0x35] + dla $8, 65538($8) +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 2 # encoding: [0x02,0x00,0x21,0x34] +# CHECK: daddu $8, $1, $8 # encoding: [0x2d,0x40,0x28,0x00] + dla $8, 0x100010001($8) +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: daddu $8, $1, $8 # encoding: [0x2d,0x40,0x28,0x00] + dla $8, 0x1000100010001($8) +# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, 1 # encoding: [0x01,0x00,0x21,0x34] +# CHECK: daddu $8, $1, $8 # encoding: [0x2d,0x40,0x28,0x00] + dla $8, symbol($8) +# CHECK: lui $1, %highest(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHEST, kind: fixup_Mips_HIGHEST +# CHECK: ori $1, $1, %higher(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHER, kind: fixup_Mips_HIGHER +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, %hi(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: daddu $8, $1, $8 # encoding: [0x2d,0x40,0x28,0x00] + +# When using $at. + dla $at, 20 +# CHECK: ori $1, $zero, 20 # encoding: [0x14,0x00,0x01,0x34] + dla $8, 20($at) +# CHECK: ori $8, $1, 20 # encoding: [0x14,0x00,0x28,0x34] + dla $at, 20($9) +# CHECK: ori $1, $9, 20 # encoding: [0x14,0x00,0x21,0x35] + dla $at, 20($at) +# CHECK: ori $1, $1, 20 # encoding: [0x14,0x00,0x21,0x34] +# NOTE: Some of the following $at-related expansions are non-sensical, but they +# are consistent with GAS' behavior. + dla $at, symbol +# CHECK: lui $1, %highest(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHEST, kind: fixup_Mips_HIGHEST +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %higher(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHER, kind: fixup_Mips_HIGHER +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: dsll32 $1, $1, 0 # encoding: [0x3c,0x08,0x01,0x00] +# CHECK: daddu $1, $1, $1 # encoding: [0x2d,0x08,0x21,0x00] + dla $8, symbol($at) +# CHECK: lui $8, %highest(symbol) # encoding: [A,A,0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHEST, kind: fixup_Mips_HIGHEST +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %higher(symbol) # encoding: [A,A,0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHER, kind: fixup_Mips_HIGHER +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: dsll32 $8, $8, 0 # encoding: [0x3c,0x40,0x08,0x00] +# CHECK: daddu $8, $8, $1 # encoding: [0x2d,0x40,0x01,0x01] +# CHECK: daddu $8, $8, $1 # encoding: [0x2d,0x40,0x01,0x01] + dla $at, symbol($9) +# CHECK: lui $1, %highest(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHEST, kind: fixup_Mips_HIGHEST +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $1, $1, %higher(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHER, kind: fixup_Mips_HIGHER +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: dsll32 $1, $1, 0 # encoding: [0x3c,0x08,0x01,0x00] +# CHECK: daddu $1, $1, $1 # encoding: [0x2d,0x08,0x21,0x00] +# CHECK: daddu $1, $1, $9 # encoding: [0x2d,0x08,0x29,0x00] + dla $at, symbol($at) +# CHECK: lui $1, %highest(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHEST, kind: fixup_Mips_HIGHEST +# CHECK: ori $1, $1, %higher(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHER, kind: fixup_Mips_HIGHER +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, %hi(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: dsll $1, $1, 16 # encoding: [0x38,0x0c,0x01,0x00] +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: daddu $1, $1, $1 # encoding: [0x2d,0x08,0x21,0x00] + + .set push +# Test la with a 64-bit architecture at the .module-level and +# a 32/64-bit architecture at the .set-level: + .set mips32 + la $8, symbol +# CHECK: lui $8, %hi(symbol) # encoding: [A,A,0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %lo(symbol) # encoding: [A,A,0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 + .set mips64 + la $8, symbol +# CHECK: lui $8, %highest(symbol) # encoding: [A,A,0x08,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHEST, kind: fixup_Mips_HIGHEST +# CHECK: lui $1, %hi(symbol) # encoding: [A,A,0x01,0x3c] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16 +# CHECK: ori $8, $8, %higher(symbol) # encoding: [A,A,0x08,0x35] +# CHECK: # fixup A - offset: 0, value: symbol@HIGHER, kind: fixup_Mips_HIGHER +# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34] +# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16 +# CHECK: dsll32 $8, $8, 0 # encoding: [0x3c,0x40,0x08,0x00] +# CHECK: daddu $8, $8, $1 # encoding: [0x2d,0x40,0x01,0x01] + .set pop