Skip to content

Commit b9b39db

Browse files
authored
RISCVAsmParser: Don't treat operands with relocation specifier as parse-time constants
An immediate operand is encoded as an `MCExpr`, with `RISCVMCExpr` specifying an operand that includes a relocation specifier. When https://reviews.llvm.org/D23568 added initial fixup and relocation support in 2017, it adapted code from `PPCMCExpr` (for `@l` `@ha`) to evaluate the `RISCVMCExpr` operand. (PPCAsmParser had considerable technical debt, though I’ve recently streamlined it somewhat, e.g. 8560da2) Evaluating RISCVMCExpr during parsing is unnecessary. For example, there's no need to treat `lui a0, %hi(2)` differently from `lui a0, %hi(foo)` when foo has not been defined yet. This evaluation introduces unnecessary complexity. For instance, parser functions require an extra check like `VK == RISCVMCExpr::VK_None`, as seen in these examples: ``` if (!evaluateConstantImm(getImm(), Imm, VK) || VK != RISCVMCExpr::VK_None) return IsConstantImm && isUInt<N>(Imm) && VK == RISCVMCExpr::VK_None; ``` This PR eliminates the parse-time evaluation of `RISCVMCExpr`, aligning it more closely with other targets. --- `abs = 0x12345; lui t3, %hi(abs)` now generates R_RISCV_HI20/R_RISCV_RELAX with linker relaxation. (Tested by test/MC/RISCV/linker-relaxation.s) (Notably, since commit ba2de8f in lld/ELF, the linker can handle R_RISCV_HI relocations with a symbol index of 0 in -pie mode.) Pull Request: #133377
1 parent fe6fb91 commit b9b39db

13 files changed

+101
-159
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

+37-78
Original file line numberDiff line numberDiff line change
@@ -526,15 +526,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
526526
bool isGPRAsFPR32() const { return isGPRF32() && Reg.IsGPRAsFPR; }
527527
bool isGPRPairAsFPR64() const { return isGPRPair() && Reg.IsGPRAsFPR; }
528528

529-
static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
530-
RISCVMCExpr::Specifier &VK) {
531-
if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
532-
VK = RE->getSpecifier();
533-
return RE->evaluateAsConstant(Imm);
534-
}
535-
529+
static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
536530
if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
537-
VK = RISCVMCExpr::VK_None;
538531
Imm = CE->getValue();
539532
return true;
540533
}
@@ -549,7 +542,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
549542
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
550543
if (!isImm())
551544
return false;
552-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
545+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
553546
bool IsValid;
554547
if (!IsConstantImm)
555548
IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
@@ -564,7 +557,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
564557
int64_t Imm;
565558
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
566559
// Must be of 'immediate' type but not a constant.
567-
if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
560+
if (!isImm() || evaluateConstantImm(getImm(), Imm))
568561
return false;
569562
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
570563
VK == RISCVMCExpr::VK_None;
@@ -574,7 +567,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
574567
int64_t Imm;
575568
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
576569
// Must be of 'immediate' type but not a constant.
577-
if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
570+
if (!isImm() || evaluateConstantImm(getImm(), Imm))
578571
return false;
579572
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
580573
(VK == RISCVMCExpr::VK_CALL || VK == RISCVMCExpr::VK_CALL_PLT);
@@ -584,7 +577,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
584577
int64_t Imm;
585578
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
586579
// Must be of 'immediate' type but not a constant.
587-
if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
580+
if (!isImm() || evaluateConstantImm(getImm(), Imm))
588581
return false;
589582
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
590583
VK == RISCVMCExpr::VK_CALL;
@@ -594,7 +587,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
594587
int64_t Imm;
595588
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
596589
// Must be of 'immediate' type but not a constant.
597-
if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
590+
if (!isImm() || evaluateConstantImm(getImm(), Imm))
598591
return false;
599592
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
600593
VK == RISCVMCExpr::VK_TPREL_ADD;
@@ -604,7 +597,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
604597
int64_t Imm;
605598
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
606599
// Must be of 'immediate' type but not a constant.
607-
if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
600+
if (!isImm() || evaluateConstantImm(getImm(), Imm))
608601
return false;
609602
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
610603
VK == RISCVMCExpr::VK_TLSDESC_CALL;
@@ -649,61 +642,48 @@ struct RISCVOperand final : public MCParsedAsmOperand {
649642

650643
bool isImmXLenLI() const {
651644
int64_t Imm;
652-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
653645
if (!isImm())
654646
return false;
655-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
656-
if (VK == RISCVMCExpr::VK_LO || VK == RISCVMCExpr::VK_PCREL_LO ||
657-
VK == RISCVMCExpr::VK_TLSDESC_LOAD_LO ||
658-
VK == RISCVMCExpr::VK_TLSDESC_ADD_LO)
659-
return true;
660647
// Given only Imm, ensuring that the actually specified constant is either
661648
// a signed or unsigned 64-bit number is unfortunately impossible.
662-
if (IsConstantImm) {
663-
return VK == RISCVMCExpr::VK_None &&
664-
(isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
665-
}
649+
if (evaluateConstantImm(getImm(), Imm))
650+
return isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm));
666651

667652
return RISCVAsmParser::isSymbolDiff(getImm());
668653
}
669654

670655
bool isImmXLenLI_Restricted() const {
671656
int64_t Imm;
672-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
673657
if (!isImm())
674658
return false;
675-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
659+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
676660
// 'la imm' supports constant immediates only.
677-
return IsConstantImm && (VK == RISCVMCExpr::VK_None) &&
661+
return IsConstantImm &&
678662
(isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
679663
}
680664

681665
template <unsigned N> bool isUImm() const {
682666
int64_t Imm;
683-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
684667
if (!isImm())
685668
return false;
686-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
687-
return IsConstantImm && isUInt<N>(Imm) && VK == RISCVMCExpr::VK_None;
669+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
670+
return IsConstantImm && isUInt<N>(Imm);
688671
}
689672

690673
template <unsigned N, unsigned S> bool isUImmShifted() const {
691674
int64_t Imm;
692-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
693675
if (!isImm())
694676
return false;
695-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
696-
return IsConstantImm && isShiftedUInt<N, S>(Imm) &&
697-
VK == RISCVMCExpr::VK_None;
677+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
678+
return IsConstantImm && isShiftedUInt<N, S>(Imm);
698679
}
699680

700681
template <class Pred> bool isUImmPred(Pred p) const {
701682
int64_t Imm;
702-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
703683
if (!isImm())
704684
return false;
705-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
706-
return IsConstantImm && p(Imm) && VK == RISCVMCExpr::VK_None;
685+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
686+
return IsConstantImm && p(Imm);
707687
}
708688

709689
bool isUImmLog2XLen() const {
@@ -791,22 +771,18 @@ struct RISCVOperand final : public MCParsedAsmOperand {
791771

792772
template <unsigned N> bool isSImm() const {
793773
int64_t Imm;
794-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
795774
if (!isImm())
796775
return false;
797-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
798-
return IsConstantImm && isInt<N>(fixImmediateForRV32(Imm, isRV64Imm())) &&
799-
VK == RISCVMCExpr::VK_None;
776+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
777+
return IsConstantImm && isInt<N>(fixImmediateForRV32(Imm, isRV64Imm()));
800778
}
801779

802780
template <class Pred> bool isSImmPred(Pred p) const {
803781
int64_t Imm;
804-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
805782
if (!isImm())
806783
return false;
807-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
808-
return IsConstantImm && p(fixImmediateForRV32(Imm, isRV64Imm())) &&
809-
VK == RISCVMCExpr::VK_None;
784+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
785+
return IsConstantImm && p(fixImmediateForRV32(Imm, isRV64Imm()));
810786
}
811787

812788
bool isSImm5() const { return isSImm<5>(); }
@@ -867,15 +843,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
867843
bool IsValid;
868844
if (!isImm())
869845
return false;
870-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
846+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
871847
if (!IsConstantImm)
872848
IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
873849
else
874850
IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
875851
return IsValid &&
876-
((IsConstantImm && VK == RISCVMCExpr::VK_None) ||
877-
VK == RISCVMCExpr::VK_LO || VK == RISCVMCExpr::VK_PCREL_LO ||
878-
VK == RISCVMCExpr::VK_TPREL_LO ||
852+
(IsConstantImm || VK == RISCVMCExpr::VK_LO ||
853+
VK == RISCVMCExpr::VK_PCREL_LO || VK == RISCVMCExpr::VK_TPREL_LO ||
879854
VK == RISCVMCExpr::VK_TLSDESC_LOAD_LO ||
880855
VK == RISCVMCExpr::VK_TLSDESC_ADD_LO);
881856
}
@@ -900,40 +875,27 @@ struct RISCVOperand final : public MCParsedAsmOperand {
900875
bool isUImm20LUI() const {
901876
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
902877
int64_t Imm;
903-
bool IsValid;
904878
if (!isImm())
905879
return false;
906-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
907-
if (!IsConstantImm) {
908-
IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
909-
return IsValid &&
910-
(VK == RISCVMCExpr::VK_HI || VK == RISCVMCExpr::VK_TPREL_HI);
911-
} else {
912-
return isUInt<20>(Imm) &&
913-
(VK == RISCVMCExpr::VK_None || VK == RISCVMCExpr::VK_HI ||
914-
VK == RISCVMCExpr::VK_TPREL_HI);
915-
}
880+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
881+
if (IsConstantImm)
882+
return isUInt<20>(Imm);
883+
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
884+
(VK == RISCVMCExpr::VK_HI || VK == RISCVMCExpr::VK_TPREL_HI);
916885
}
917886

918887
bool isUImm20AUIPC() const {
919888
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
920889
int64_t Imm;
921-
bool IsValid;
922890
if (!isImm())
923891
return false;
924-
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
925-
if (!IsConstantImm) {
926-
IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
927-
return IsValid &&
928-
(VK == RISCVMCExpr::VK_PCREL_HI || VK == RISCVMCExpr::VK_GOT_HI ||
929-
VK == RISCVMCExpr::VK_TLS_GOT_HI ||
930-
VK == RISCVMCExpr::VK_TLS_GD_HI ||
931-
VK == RISCVMCExpr::VK_TLSDESC_HI);
932-
}
892+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
893+
if (IsConstantImm)
894+
return isUInt<20>(Imm);
933895

934-
return isUInt<20>(Imm) &&
935-
(VK == RISCVMCExpr::VK_None || VK == RISCVMCExpr::VK_PCREL_HI ||
936-
VK == RISCVMCExpr::VK_GOT_HI || VK == RISCVMCExpr::VK_TLS_GOT_HI ||
896+
return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
897+
(VK == RISCVMCExpr::VK_PCREL_HI || VK == RISCVMCExpr::VK_GOT_HI ||
898+
VK == RISCVMCExpr::VK_TLS_GOT_HI ||
937899
VK == RISCVMCExpr::VK_TLS_GD_HI ||
938900
VK == RISCVMCExpr::VK_TLSDESC_HI);
939901
}
@@ -1159,8 +1121,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
11591121
static void addExpr(MCInst &Inst, const MCExpr *Expr, bool IsRV64Imm) {
11601122
assert(Expr && "Expr shouldn't be null!");
11611123
int64_t Imm = 0;
1162-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
1163-
bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1124+
bool IsConstant = evaluateConstantImm(Expr, Imm);
11641125

11651126
if (IsConstant)
11661127
Inst.addOperand(
@@ -1209,9 +1170,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
12091170
assert(N == 1 && "Invalid number of operands!");
12101171
int64_t Imm = 0;
12111172
if (Kind == KindTy::Immediate) {
1212-
RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
1213-
[[maybe_unused]] bool IsConstantImm =
1214-
evaluateConstantImm(getImm(), Imm, VK);
1173+
[[maybe_unused]] bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
12151174
assert(IsConstantImm && "Invalid VTypeI Operand!");
12161175
} else {
12171176
Imm = getVType();

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp

-27
Original file line numberDiff line numberDiff line change
@@ -169,30 +169,3 @@ StringRef RISCVMCExpr::getSpecifierName(Specifier S) {
169169
}
170170
llvm_unreachable("Invalid ELF symbol kind");
171171
}
172-
173-
bool RISCVMCExpr::evaluateAsConstant(int64_t &Res) const {
174-
MCValue Value;
175-
if (specifier != VK_LO && specifier != VK_HI)
176-
return false;
177-
178-
if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr))
179-
return false;
180-
181-
if (!Value.isAbsolute())
182-
return false;
183-
184-
Res = evaluateAsInt64(Value.getConstant());
185-
return true;
186-
}
187-
188-
int64_t RISCVMCExpr::evaluateAsInt64(int64_t Value) const {
189-
switch (specifier) {
190-
default:
191-
llvm_unreachable("Invalid kind");
192-
case VK_LO:
193-
return SignExtend64<12>(Value);
194-
case VK_HI:
195-
// Add 1 if bit 11 is 1, to compensate for low 12 bits being negative.
196-
return ((Value + 0x800) >> 12) & 0xfffff;
197-
}
198-
}

llvm/test/MC/RISCV/insn.s

+4-4
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,12 @@ target:
146146
# CHECK-OBJ: fmadd.s fa0, fa1, fa2, fa3, rne
147147
.insn r4 MADD, 0, 0, fa0, fa1, fa2, fa3
148148

149-
# CHECK-ASM: .insn i 3, 5, t1, -2048(t2)
150-
# CHECK-ASM: encoding: [0x03,0xd3,0x03,0x80]
149+
# CHECK-ASM: .insn i 3, 5, t1, %lo(2048)(t2)
150+
# CHECK-ASM: encoding: [0x03,0xd3,0bAAAA0011,A]
151151
# CHECK-OBJ: lhu t1, -0x800(t2)
152152
.insn i 0x3, 0x5, x6, %lo(2048)(x7)
153-
# CHECK-ASM: .insn i 3, 5, t1, -2048(t2)
154-
# CHECK-ASM: encoding: [0x03,0xd3,0x03,0x80]
153+
# CHECK-ASM: .insn i 3, 5, t1, %lo(2048)(t2)
154+
# CHECK-ASM: encoding: [0x03,0xd3,0bAAAA0011,A]
155155
# CHECK-OBJ: lhu t1, -0x800(t2)
156156
.insn i LOAD, 0x5, x6, %lo(2048)(x7)
157157

llvm/test/MC/RISCV/linker-relaxation.s

+12-2
Original file line numberDiff line numberDiff line change
@@ -137,18 +137,28 @@ sb t1, %pcrel_lo(2b)(a2)
137137
# RELAX-FIXUP: fixup A - offset: 0, value: %pcrel_lo(.Ltmp1), kind: fixup_riscv_pcrel_lo12_s
138138
# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax
139139

140+
## %hi/%lo on an absolute symbol (not yet defined) leads to relocations when relaxation is enabled.
140141
lui t2, %hi(abs)
141142
# NORELAX-RELOC-NOT: R_RISCV_
142143
# RELAX-RELOC: R_RISCV_HI20 - 0x12345
143144
# RELAX-RELOC-NEXT: R_RISCV_RELAX - 0x0
144145
# RELAX-FIXUP: fixup A - offset: 0, value: %hi(abs), kind: fixup_riscv_hi20
145146
# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax
146147

148+
addi t2, t2, %lo(abs)
149+
# NORELAX-RELOC-NOT: R_RISCV_
150+
# RELAX-RELOC: R_RISCV_LO12_I - 0x12345
151+
# RELAX-RELOC-NEXT: R_RISCV_RELAX - 0x0
152+
# RELAX-FIXUP: fixup A - offset: 0, value: %lo(abs), kind: fixup_riscv_lo12_i
153+
# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax
154+
147155
.set abs, 0x12345
148156

149157
lui t3, %hi(abs)
150-
# RELAX-RELOC-NOT: R_RISCV_
151-
# RELAX-FIXUP-NOT: fixup
158+
# RELAX-RELOC: R_RISCV_HI20 - 0x12345
159+
# RELAX-RELOC-NEXT: R_RISCV_RELAX - 0x0
160+
# RELAX-FIXUP: fixup A - offset: 0, value: %hi(74565), kind: fixup_riscv_hi20
161+
# RELAX-FIXUP: fixup B - offset: 0, value: 0, kind: fixup_riscv_relax
152162

153163
# Check that a relocation is not emitted for a symbol difference which has
154164
# been folded to a fixup with an absolute value. This can happen when a

llvm/test/MC/RISCV/rv32i-aliases-valid.s

+3-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ li x12, 0x80000000
8383
# CHECK-ALIAS: li a2, -1
8484
li x12, 0xFFFFFFFF
8585

86-
# CHECK-INST: addi a0, zero, 1110
87-
# CHECK-ALIAS: li a0, 1110
86+
# CHECK-ASM-NOALIAS: addi a0, zero, %lo(1193046)
87+
# CHECK-OBJ-NOALIAS: addi a0, zero, 1110
88+
# CHECK-ASM: addi a0, zero, %lo(1193046)
8889
li a0, %lo(0x123456)
8990

9091
# CHECK-OBJ-NOALIAS: addi a0, zero, 0

llvm/test/MC/RISCV/rv64i-aliases-valid.s

+2-2
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ li x13, 0xffffffff55555556
192192
# CHECK-S-OBJ-NEXT: addi t0, t0, -1365
193193
li x5, -2147485013
194194

195-
# CHECK-INST: addi a0, zero, 1110
196-
# CHECK-ALIAS: li a0, 1110
195+
# CHECK-ASM: addi a0, zero, %lo(1193046)
196+
# CHECK-OBJ: addi a0, zero, %lo(1193046)
197197
li a0, %lo(0x123456)
198198

199199
# CHECK-OBJ-NOALIAS: addi a0, zero, 0

llvm/test/MC/RISCV/rv64i-valid.s

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ lwu x2, +4(x3)
1515
# CHECK-ASM-AND-OBJ: lwu tp, -2048(t0)
1616
# CHECK-ASM: encoding: [0x03,0xe2,0x02,0x80]
1717
lwu x4, -2048(x5)
18-
# CHECK-ASM-AND-OBJ: lwu t1, -2048(t2)
19-
# CHECK-ASM: encoding: [0x03,0xe3,0x03,0x80]
18+
# CHECK-ASM: lwu t1, %lo(2048)(t2) # encoding: [0x03,0xe3,0bAAAA0011,A]
19+
# CHECK-OBJ: lwu t1, -2048(t2)
2020
lwu x6, %lo(2048)(x7)
2121
# CHECK-ASM-AND-OBJ: lwu s0, 2047(s1)
2222
# CHECK-ASM: encoding: [0x03,0xe4,0xf4,0x7f]
@@ -25,8 +25,8 @@ lwu x8, 2047(x9)
2525
# CHECK-ASM-AND-OBJ: ld a0, -2048(a1)
2626
# CHECK-ASM: encoding: [0x03,0xb5,0x05,0x80]
2727
ld x10, -2048(x11)
28-
# CHECK-ASM-AND-OBJ: ld a2, -2048(a3)
29-
# CHECK-ASM: encoding: [0x03,0xb6,0x06,0x80]
28+
# CHECK-ASM: ld a2, %lo(2048)(a3) # encoding: [0x03,0xb6,0bAAAA0110,A]
29+
# CHECK-OBJ: ld a2, -2048(a3)
3030
ld x12, %lo(2048)(x13)
3131
# CHECK-ASM-AND-OBJ: ld a4, 2047(a5)
3232
# CHECK-ASM: encoding: [0x03,0xb7,0xf7,0x7f]
@@ -35,8 +35,8 @@ ld x14, 2047(x15)
3535
# CHECK-ASM-AND-OBJ: sd a6, -2048(a7)
3636
# CHECK-ASM: encoding: [0x23,0xb0,0x08,0x81]
3737
sd x16, -2048(x17)
38-
# CHECK-ASM-AND-OBJ: sd s2, -2048(s3)
39-
# CHECK-ASM: encoding: [0x23,0xb0,0x29,0x81]
38+
# CHECK-ASM: sd s2, %lo(2048)(s3) # encoding: [0x23'A',0xb0'A',0x29'A',0x01'A']
39+
# CHECK-OBJ: sd s2, -2048(s3)
4040
sd x18, %lo(2048)(x19)
4141
# CHECK-ASM-AND-OBJ: sd s4, 2047(s5)
4242
# CHECK-ASM: encoding: [0xa3,0xbf,0x4a,0x7f]

0 commit comments

Comments
 (0)