diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -139,6 +139,9 @@ // Helper to emit pseudo instruction "lla" used in PC-rel addressing. void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); + // Helper to emit pseudo instruction "lga" used in GOT-rel addressing. + void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); + // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing. void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); @@ -3088,29 +3091,34 @@ RISCV::ADDI, IDLoc, Out); } +void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, + MCStreamer &Out) { + // The load global address pseudo-instruction "lga" is used in GOT-indirect + // addressing of global symbols: + // lga rdest, symbol + // expands to + // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) + // Lx rdest, %pcrel_lo(TmpLabel)(rdest) + MCOperand DestReg = Inst.getOperand(0); + const MCExpr *Symbol = Inst.getOperand(1).getExpr(); + unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; + emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_GOT_HI, + SecondOpcode, IDLoc, Out); +} + void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) { // The load address pseudo-instruction "la" is used in PC-relative and // GOT-indirect addressing of global symbols: // la rdest, symbol - // expands to either (for non-PIC) - // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) - // ADDI rdest, rdest, %pcrel_lo(TmpLabel) + // is an alias for either (for non-PIC) + // lla rdest, symbol // or (for PIC) - // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) - // Lx rdest, %pcrel_lo(TmpLabel)(rdest) - MCOperand DestReg = Inst.getOperand(0); - const MCExpr *Symbol = Inst.getOperand(1).getExpr(); - unsigned SecondOpcode; - RISCVMCExpr::VariantKind VKHi; - if (ParserOptions.IsPicEnabled) { - SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; - VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; - } else { - SecondOpcode = RISCV::ADDI; - VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; - } - emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); + // lga rdest, symbol + if (ParserOptions.IsPicEnabled) + emitLoadGlobalAddress(Inst, IDLoc, Out); + else + emitLoadLocalAddress(Inst, IDLoc, Out); } void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, @@ -3438,6 +3446,9 @@ case RISCV::PseudoLLA: emitLoadLocalAddress(Inst, IDLoc, Out); return false; + case RISCV::PseudoLGA: + emitLoadGlobalAddress(Inst, IDLoc, Out); + return false; case RISCV::PseudoLA: emitLoadAddress(Inst, IDLoc, Out); return false; diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp --- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -371,9 +371,9 @@ bool expandLoadLocalAddress(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NextMBBI); - bool expandLoadAddress(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - MachineBasicBlock::iterator &NextMBBI); + bool expandLoadGlobalAddress(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI); bool expandLoadTLSIEAddress(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NextMBBI); @@ -431,8 +431,8 @@ switch (MBBI->getOpcode()) { case RISCV::PseudoLLA: return expandLoadLocalAddress(MBB, MBBI, NextMBBI); - case RISCV::PseudoLA: - return expandLoadAddress(MBB, MBBI, NextMBBI); + case RISCV::PseudoLGA: + return expandLoadGlobalAddress(MBB, MBBI, NextMBBI); case RISCV::PseudoLA_TLS_IE: return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI); case RISCV::PseudoLA_TLS_GD: @@ -480,17 +480,12 @@ RISCV::ADDI); } -bool RISCVPreRAExpandPseudo::expandLoadAddress( +bool RISCVPreRAExpandPseudo::expandLoadGlobalAddress( MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NextMBBI) { MachineFunction *MF = MBB.getParent(); const auto &STI = MF->getSubtarget(); - // When HWASAN is used and tagging of global variables is enabled - // they should be accessed via the GOT, since the tagged address of a global - // is incompatible with existing code models. This also applies to non-pic - // mode. - assert(MF->getTarget().isPositionIndependent() || STI.allowTaggedGlobals()); unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW; return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_GOT_HI, SecondOpcode); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -371,8 +371,9 @@ // have memop! In fact, starting from FIRST_TARGET_MEMORY_OPCODE all // opcodes will be thought as target memory ops! - // Load address. - LA = ISD::FIRST_TARGET_MEMORY_OPCODE, + // Represents an AUIPC+L[WD] pair. Selected to PseudoLGA. + LGA = ISD::FIRST_TARGET_MEMORY_OPCODE, + // Load initial exec thread-local address. LA_TLS_IE, TH_LWD, diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -5278,7 +5278,7 @@ return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr); // Use PC-relative addressing to access the GOT for this symbol, then load - // the address from the GOT. This generates the pattern (PseudoLA sym), + // the address from the GOT. This generates the pattern (PseudoLGA sym), // which expands to (ld (addi (auipc %got_pcrel_hi(sym)) %pcrel_lo(auipc))). MachineFunction &MF = DAG.getMachineFunction(); MachineMemOperand *MemOp = MF.getMachineMemOperand( @@ -5287,7 +5287,7 @@ MachineMemOperand::MOInvariant, LLT(Ty.getSimpleVT()), Align(Ty.getFixedSizeInBits() / 8)); SDValue Load = - DAG.getMemIntrinsicNode(RISCVISD::LA, DL, DAG.getVTList(Ty, MVT::Other), + DAG.getMemIntrinsicNode(RISCVISD::LGA, DL, DAG.getVTList(Ty, MVT::Other), {DAG.getEntryNode(), Addr}, Ty, MemOp); return Load; } @@ -15279,8 +15279,8 @@ NODE_NAME_CASE(ADD_LO) NODE_NAME_CASE(HI) NODE_NAME_CASE(LLA) + NODE_NAME_CASE(LGA) NODE_NAME_CASE(ADD_TPREL) - NODE_NAME_CASE(LA) NODE_NAME_CASE(LA_TLS_IE) NODE_NAME_CASE(LA_TLS_GD) NODE_NAME_CASE(MULHSU) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -84,14 +84,14 @@ def riscv_add_lo : SDNode<"RISCVISD::ADD_LO", SDTIntBinOp>; def riscv_hi : SDNode<"RISCVISD::HI", SDTIntUnaryOp>; def riscv_lla : SDNode<"RISCVISD::LLA", SDTIntUnaryOp>; +def riscv_lga : SDNode<"RISCVISD::LGA", SDTLoad, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; def riscv_add_tprel : SDNode<"RISCVISD::ADD_TPREL", SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisInt<0>]>>; -def riscv_la : SDNode<"RISCVISD::LA", SDTLoad, - [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; def riscv_la_tls_ie : SDNode<"RISCVISD::LA_TLS_IE", SDTLoad, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; def riscv_la_tls_gd : SDNode<"RISCVISD::LA_TLS_GD", SDTIntUnaryOp>; @@ -1599,13 +1599,18 @@ def : Pat<(riscv_lla tjumptable:$in), (PseudoLLA tjumptable:$in)>; def : Pat<(riscv_lla tconstpool:$in), (PseudoLLA tconstpool:$in)>; +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0, + isAsmParserOnly = 1 in +def PseudoLGA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], + "lga", "$dst, $src">; + +def : Pat<(riscv_lga tglobaladdr:$in), (PseudoLGA tglobaladdr:$in)>; + let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0, isAsmParserOnly = 1 in def PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], "la", "$dst, $src">; -def : Pat<(riscv_la tglobaladdr:$in), (PseudoLA tglobaladdr:$in)>; - let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0, isAsmParserOnly = 1 in def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], diff --git a/llvm/test/MC/RISCV/rvi-pseudos-invalid.s b/llvm/test/MC/RISCV/rvi-pseudos-invalid.s --- a/llvm/test/MC/RISCV/rvi-pseudos-invalid.s +++ b/llvm/test/MC/RISCV/rvi-pseudos-invalid.s @@ -11,6 +11,16 @@ lla x1, %hi(foo) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name lla x1, %lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, 1234 # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, %pcrel_hi(1234) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, %pcrel_lo(1234) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, %pcrel_hi(foo) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, %pcrel_lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, %hi(1234) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, %lo(1234) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, %hi(foo) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name +lga x1, %lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name + la x1, 1234 # CHECK: :[[@LINE]]:8: error: operand must be a bare symbol name la x1, %pcrel_hi(1234) # CHECK: :[[@LINE]]:8: error: operand must be a bare symbol name la x1, %pcrel_lo(1234) # CHECK: :[[@LINE]]:8: error: operand must be a bare symbol name diff --git a/llvm/test/MC/RISCV/rvi-pseudos.s b/llvm/test/MC/RISCV/rvi-pseudos.s --- a/llvm/test/MC/RISCV/rvi-pseudos.s +++ b/llvm/test/MC/RISCV/rvi-pseudos.s @@ -38,158 +38,194 @@ # CHECK: addi a5, a5, %pcrel_lo(.Lpcrel_hi5) lla a5, a_symbol + (0xFF << 3) -# CHECK: .Lpcrel_hi6: +# CHECK: .Lpcrel_hi6: +# CHECK: auipc a0, %got_pcrel_hi(a_symbol) +# CHECK-RV32: lw a0, %pcrel_lo(.Lpcrel_hi6)(a0) +# CHECK-RV64: ld a0, %pcrel_lo(.Lpcrel_hi6)(a0) +lga a0, a_symbol + +# CHECK: .Lpcrel_hi7: +# CHECK: auipc a1, %got_pcrel_hi(another_symbol) +# CHECK-RV32: lw a1, %pcrel_lo(.Lpcrel_hi7)(a1) +# CHECK-RV64: ld a1, %pcrel_lo(.Lpcrel_hi7)(a1) +lga a1, another_symbol + +# CHECK: .Lpcrel_hi8: +# CHECK: auipc a2, %got_pcrel_hi(zero) +# CHECK-RV32: lw a2, %pcrel_lo(.Lpcrel_hi8)(a2) +# CHECK-RV64: ld a2, %pcrel_lo(.Lpcrel_hi8)(a2) +lga a2, zero + +# CHECK: .Lpcrel_hi9: +# CHECK: auipc a3, %got_pcrel_hi(ra) +# CHECK-RV32: lw a3, %pcrel_lo(.Lpcrel_hi9)(a3) +# CHECK-RV64: ld a3, %pcrel_lo(.Lpcrel_hi9)(a3) +lga a3, ra + +# CHECK: .Lpcrel_hi10: +# CHECK: auipc a4, %got_pcrel_hi(f1) +# CHECK-RV32: lw a4, %pcrel_lo(.Lpcrel_hi10)(a4) +# CHECK-RV64: ld a4, %pcrel_lo(.Lpcrel_hi10)(a4) +lga a4, f1 + +# CHECK: .Lpcrel_hi11: +# CHECK: auipc a5, %got_pcrel_hi(a_symbol+2040) +# CHECK-RV32: lw a5, %pcrel_lo(.Lpcrel_hi11)(a5) +# CHECK-RV64: ld a5, %pcrel_lo(.Lpcrel_hi11)(a5) +lga a5, a_symbol + (0xFF << 3) + +# CHECK: .Lpcrel_hi12: # CHECK-NOPIC: auipc a0, %pcrel_hi(a_symbol) -# CHECK-NOPIC: addi a0, a0, %pcrel_lo(.Lpcrel_hi6) +# CHECK-NOPIC: addi a0, a0, %pcrel_lo(.Lpcrel_hi12) # CHECK-PIC: auipc a0, %got_pcrel_hi(a_symbol) -# CHECK-PIC-RV32: lw a0, %pcrel_lo(.Lpcrel_hi6)(a0) -# CHECK-PIC-RV64: ld a0, %pcrel_lo(.Lpcrel_hi6)(a0) +# CHECK-PIC-RV32: lw a0, %pcrel_lo(.Lpcrel_hi12)(a0) +# CHECK-PIC-RV64: ld a0, %pcrel_lo(.Lpcrel_hi12)(a0) la a0, a_symbol -# CHECK: .Lpcrel_hi7: +# CHECK: .Lpcrel_hi13: # CHECK-NOPIC: auipc a1, %pcrel_hi(another_symbol) -# CHECK-NOPIC: addi a1, a1, %pcrel_lo(.Lpcrel_hi7) +# CHECK-NOPIC: addi a1, a1, %pcrel_lo(.Lpcrel_hi13) # CHECK-PIC: auipc a1, %got_pcrel_hi(another_symbol) -# CHECK-PIC-RV32: lw a1, %pcrel_lo(.Lpcrel_hi7)(a1) -# CHECK-PIC-RV64: ld a1, %pcrel_lo(.Lpcrel_hi7)(a1) +# CHECK-PIC-RV32: lw a1, %pcrel_lo(.Lpcrel_hi13)(a1) +# CHECK-PIC-RV64: ld a1, %pcrel_lo(.Lpcrel_hi13)(a1) la a1, another_symbol # Check that we can load the address of symbols that are spelled like a register -# CHECK: .Lpcrel_hi8: +# CHECK: .Lpcrel_hi14: # CHECK-NOPIC: auipc a2, %pcrel_hi(zero) -# CHECK-NOPIC: addi a2, a2, %pcrel_lo(.Lpcrel_hi8) +# CHECK-NOPIC: addi a2, a2, %pcrel_lo(.Lpcrel_hi14) # CHECK-PIC: auipc a2, %got_pcrel_hi(zero) -# CHECK-PIC-RV32: lw a2, %pcrel_lo(.Lpcrel_hi8)(a2) -# CHECK-PIC-RV64: ld a2, %pcrel_lo(.Lpcrel_hi8)(a2) +# CHECK-PIC-RV32: lw a2, %pcrel_lo(.Lpcrel_hi14)(a2) +# CHECK-PIC-RV64: ld a2, %pcrel_lo(.Lpcrel_hi14)(a2) la a2, zero -# CHECK: .Lpcrel_hi9: +# CHECK: .Lpcrel_hi15: # CHECK-NOPIC: auipc a3, %pcrel_hi(ra) -# CHECK-NOPIC: addi a3, a3, %pcrel_lo(.Lpcrel_hi9) +# CHECK-NOPIC: addi a3, a3, %pcrel_lo(.Lpcrel_hi15) # CHECK-PIC: auipc a3, %got_pcrel_hi(ra) -# CHECK-PIC-RV32: lw a3, %pcrel_lo(.Lpcrel_hi9)(a3) -# CHECK-PIC-RV64: ld a3, %pcrel_lo(.Lpcrel_hi9)(a3) +# CHECK-PIC-RV32: lw a3, %pcrel_lo(.Lpcrel_hi15)(a3) +# CHECK-PIC-RV64: ld a3, %pcrel_lo(.Lpcrel_hi15)(a3) la a3, ra -# CHECK: .Lpcrel_hi10: +# CHECK: .Lpcrel_hi16: # CHECK-NOPIC: auipc a4, %pcrel_hi(f1) -# CHECK-NOPIC: addi a4, a4, %pcrel_lo(.Lpcrel_hi10) +# CHECK-NOPIC: addi a4, a4, %pcrel_lo(.Lpcrel_hi16) # CHECK-PIC: auipc a4, %got_pcrel_hi(f1) -# CHECK-PIC-RV32: lw a4, %pcrel_lo(.Lpcrel_hi10)(a4) -# CHECK-PIC-RV64: ld a4, %pcrel_lo(.Lpcrel_hi10)(a4) +# CHECK-PIC-RV32: lw a4, %pcrel_lo(.Lpcrel_hi16)(a4) +# CHECK-PIC-RV64: ld a4, %pcrel_lo(.Lpcrel_hi16)(a4) la a4, f1 -# CHECK: .Lpcrel_hi11: +# CHECK: .Lpcrel_hi17: # CHECK: auipc a0, %tls_ie_pcrel_hi(a_symbol) -# CHECK-RV32: lw a0, %pcrel_lo(.Lpcrel_hi11)(a0) -# CHECK-RV64: ld a0, %pcrel_lo(.Lpcrel_hi11)(a0) +# CHECK-RV32: lw a0, %pcrel_lo(.Lpcrel_hi17)(a0) +# CHECK-RV64: ld a0, %pcrel_lo(.Lpcrel_hi17)(a0) la.tls.ie a0, a_symbol -# CHECK: .Lpcrel_hi12: +# CHECK: .Lpcrel_hi18: # CHECK: auipc a1, %tls_ie_pcrel_hi(another_symbol) -# CHECK-RV32: lw a1, %pcrel_lo(.Lpcrel_hi12)(a1) -# CHECK-RV64: ld a1, %pcrel_lo(.Lpcrel_hi12)(a1) +# CHECK-RV32: lw a1, %pcrel_lo(.Lpcrel_hi18)(a1) +# CHECK-RV64: ld a1, %pcrel_lo(.Lpcrel_hi18)(a1) la.tls.ie a1, another_symbol # Check that we can load the address of symbols that are spelled like a register -# CHECK: .Lpcrel_hi13: +# CHECK: .Lpcrel_hi19: # CHECK: auipc a2, %tls_ie_pcrel_hi(zero) -# CHECK-RV32: lw a2, %pcrel_lo(.Lpcrel_hi13)(a2) -# CHECK-RV64: ld a2, %pcrel_lo(.Lpcrel_hi13)(a2) +# CHECK-RV32: lw a2, %pcrel_lo(.Lpcrel_hi19)(a2) +# CHECK-RV64: ld a2, %pcrel_lo(.Lpcrel_hi19)(a2) la.tls.ie a2, zero -# CHECK: .Lpcrel_hi14: +# CHECK: .Lpcrel_hi20: # CHECK: auipc a3, %tls_ie_pcrel_hi(ra) -# CHECK-RV32: lw a3, %pcrel_lo(.Lpcrel_hi14)(a3) -# CHECK-RV64: ld a3, %pcrel_lo(.Lpcrel_hi14)(a3) +# CHECK-RV32: lw a3, %pcrel_lo(.Lpcrel_hi20)(a3) +# CHECK-RV64: ld a3, %pcrel_lo(.Lpcrel_hi20)(a3) la.tls.ie a3, ra -# CHECK: .Lpcrel_hi15: +# CHECK: .Lpcrel_hi21: # CHECK: auipc a4, %tls_ie_pcrel_hi(f1) -# CHECK-RV32: lw a4, %pcrel_lo(.Lpcrel_hi15)(a4) -# CHECK-RV64: ld a4, %pcrel_lo(.Lpcrel_hi15)(a4) +# CHECK-RV32: lw a4, %pcrel_lo(.Lpcrel_hi21)(a4) +# CHECK-RV64: ld a4, %pcrel_lo(.Lpcrel_hi21)(a4) la.tls.ie a4, f1 -# CHECK: .Lpcrel_hi16: +# CHECK: .Lpcrel_hi22: # CHECK: auipc a0, %tls_gd_pcrel_hi(a_symbol) -# CHECK: addi a0, a0, %pcrel_lo(.Lpcrel_hi16) +# CHECK: addi a0, a0, %pcrel_lo(.Lpcrel_hi22) la.tls.gd a0, a_symbol -# CHECK: .Lpcrel_hi17: +# CHECK: .Lpcrel_hi23: # CHECK: auipc a1, %tls_gd_pcrel_hi(another_symbol) -# CHECK: addi a1, a1, %pcrel_lo(.Lpcrel_hi17) +# CHECK: addi a1, a1, %pcrel_lo(.Lpcrel_hi23) la.tls.gd a1, another_symbol # Check that we can load the address of symbols that are spelled like a register -# CHECK: .Lpcrel_hi18: +# CHECK: .Lpcrel_hi24: # CHECK: auipc a2, %tls_gd_pcrel_hi(zero) -# CHECK: addi a2, a2, %pcrel_lo(.Lpcrel_hi18) +# CHECK: addi a2, a2, %pcrel_lo(.Lpcrel_hi24) la.tls.gd a2, zero -# CHECK: .Lpcrel_hi19: +# CHECK: .Lpcrel_hi25: # CHECK: auipc a3, %tls_gd_pcrel_hi(ra) -# CHECK: addi a3, a3, %pcrel_lo(.Lpcrel_hi19) +# CHECK: addi a3, a3, %pcrel_lo(.Lpcrel_hi25) la.tls.gd a3, ra -# CHECK: .Lpcrel_hi20: +# CHECK: .Lpcrel_hi26: # CHECK: auipc a4, %tls_gd_pcrel_hi(f1) -# CHECK: addi a4, a4, %pcrel_lo(.Lpcrel_hi20) +# CHECK: addi a4, a4, %pcrel_lo(.Lpcrel_hi26) la.tls.gd a4, f1 -# CHECK: .Lpcrel_hi21: +# CHECK: .Lpcrel_hi27: # CHECK: auipc a0, %pcrel_hi(a_symbol) -# CHECK: lb a0, %pcrel_lo(.Lpcrel_hi21)(a0) +# CHECK: lb a0, %pcrel_lo(.Lpcrel_hi27)(a0) lb a0, a_symbol -# CHECK: .Lpcrel_hi22: +# CHECK: .Lpcrel_hi28: # CHECK: auipc a1, %pcrel_hi(a_symbol) -# CHECK: lh a1, %pcrel_lo(.Lpcrel_hi22)(a1) +# CHECK: lh a1, %pcrel_lo(.Lpcrel_hi28)(a1) lh a1, a_symbol -# CHECK: .Lpcrel_hi23: +# CHECK: .Lpcrel_hi29: # CHECK: auipc a2, %pcrel_hi(a_symbol) -# CHECK: lhu a2, %pcrel_lo(.Lpcrel_hi23)(a2) +# CHECK: lhu a2, %pcrel_lo(.Lpcrel_hi29)(a2) lhu a2, a_symbol -# CHECK: .Lpcrel_hi24: +# CHECK: .Lpcrel_hi30: # CHECK: auipc a3, %pcrel_hi(a_symbol) -# CHECK: lw a3, %pcrel_lo(.Lpcrel_hi24)(a3) +# CHECK: lw a3, %pcrel_lo(.Lpcrel_hi30)(a3) lw a3, a_symbol -# CHECK: .Lpcrel_hi25: +# CHECK: .Lpcrel_hi31: # CHECK: auipc a4, %pcrel_hi(a_symbol) -# CHECK: sb a3, %pcrel_lo(.Lpcrel_hi25)(a4) +# CHECK: sb a3, %pcrel_lo(.Lpcrel_hi31)(a4) sb a3, a_symbol, a4 -# CHECK: .Lpcrel_hi26: +# CHECK: .Lpcrel_hi32: # CHECK: auipc a4, %pcrel_hi(a_symbol) -# CHECK: sh a3, %pcrel_lo(.Lpcrel_hi26)(a4) +# CHECK: sh a3, %pcrel_lo(.Lpcrel_hi32)(a4) sh a3, a_symbol, a4 -# CHECK: .Lpcrel_hi27: +# CHECK: .Lpcrel_hi33: # CHECK: auipc a4, %pcrel_hi(a_symbol) -# CHECK: sw a3, %pcrel_lo(.Lpcrel_hi27)(a4) +# CHECK: sw a3, %pcrel_lo(.Lpcrel_hi33)(a4) sw a3, a_symbol, a4 # Check that we can load the address of symbols that are spelled like a register -# CHECK: .Lpcrel_hi28: +# CHECK: .Lpcrel_hi34: # CHECK: auipc a2, %pcrel_hi(zero) -# CHECK: lw a2, %pcrel_lo(.Lpcrel_hi28)(a2) +# CHECK: lw a2, %pcrel_lo(.Lpcrel_hi34)(a2) lw a2, zero -# CHECK: .Lpcrel_hi29: +# CHECK: .Lpcrel_hi35: # CHECK: auipc a4, %pcrel_hi(zero) -# CHECK: sw a3, %pcrel_lo(.Lpcrel_hi29)(a4) +# CHECK: sw a3, %pcrel_lo(.Lpcrel_hi35)(a4) sw a3, zero, a4 ## Check that a complex expression can be simplified and matched. -# CHECK: .Lpcrel_hi30: +# CHECK: .Lpcrel_hi36: # CHECK: auipc a5, %pcrel_hi((255+a_symbol)-4) -# CHECK: addi a5, a5, %pcrel_lo(.Lpcrel_hi30) +# CHECK: addi a5, a5, %pcrel_lo(.Lpcrel_hi36) lla a5, (0xFF + a_symbol) - 4 ## Check that we don't double-parse a top-level minus. -# CHECK: .Lpcrel_hi31: +# CHECK: .Lpcrel_hi37: # CHECK: auipc a5, %pcrel_hi(a_symbol-4) -# CHECK: addi a5, a5, %pcrel_lo(.Lpcrel_hi31) +# CHECK: addi a5, a5, %pcrel_lo(.Lpcrel_hi37) lla a5, a_symbol - 4