Skip to content

Commit 0fdc917

Browse files
[LLVM][AArch64]Add compare-and-branch assembly/disassembly instructions
This patch adds the assembly/disassembly for the following instructions: CBB<cc>, CBH<cc>, CB<cc>(immediate), CB<cc>(register) CBBLE, CBBLO, CBBLS, CBBLT CBHLE, CBHLO, CBHLS, CBHLT CBGE, CBHS, CBLE, CBLS (immediate) CBLE, CBLO, CBLS, CBLT(register) According to [1] [1]https://developer.arm.com/documentation/ddi0602 Co-authored-by: Momchil Velikov [email protected] Co-authored-by: Spencer Abson [email protected]
1 parent c980a20 commit 0fdc917

File tree

13 files changed

+1508
-0
lines changed

13 files changed

+1508
-0
lines changed

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,46 @@ def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{
388388
let ParserMatchClass = AsmImmRange<0, 65535>;
389389
}
390390

391+
def uimm6_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
392+
let ParserMatchClass = UImm6Operand;
393+
}
394+
395+
def uimm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 64; }]> {
396+
let ParserMatchClass = UImm6Operand;
397+
}
398+
399+
def UImm6Plus1Operand : AsmOperandClass {
400+
let Name = "UImm6P1";
401+
let DiagnosticType = "InvalidImm1_64";
402+
let RenderMethod = "addImmOperands";
403+
let ParserMethod = "tryParseAdjImm0_63<-1>";
404+
let PredicateMethod = "isImmInRange<0,63>";
405+
}
406+
407+
def UImm6Minus1Operand : AsmOperandClass {
408+
let Name = "UImm6M1";
409+
let DiagnosticType = "InvalidImmM1_62";
410+
let RenderMethod = "addImmOperands";
411+
let ParserMethod = "tryParseAdjImm0_63<1>";
412+
let PredicateMethod = "isImmInRange<0,63>";
413+
}
414+
415+
def uimm6p1_32b : Operand<i32> {
416+
let ParserMatchClass = UImm6Plus1Operand;
417+
}
418+
419+
def uimm6p1_64b : Operand<i64> {
420+
let ParserMatchClass = UImm6Plus1Operand;
421+
}
422+
423+
def uimm6m1_32b : Operand<i32> {
424+
let ParserMatchClass = UImm6Minus1Operand;
425+
}
426+
427+
def uimm6m1_64b : Operand<i64> {
428+
let ParserMatchClass = UImm6Minus1Operand;
429+
}
430+
391431
def SImm9Operand : SImmOperand<9>;
392432
def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
393433
let ParserMatchClass = SImm9Operand;
@@ -657,6 +697,7 @@ class PCRelLabel<int N> : BranchTarget<N> {
657697
def BranchTarget14Operand : BranchTarget<14>;
658698
def BranchTarget26Operand : BranchTarget<26>;
659699
def PCRelLabel19Operand : PCRelLabel<19>;
700+
def PCRelLabel9Operand : PCRelLabel<9>;
660701

661702
def MovWSymbolG3AsmOperand : AsmOperandClass {
662703
let Name = "MovWSymbolG3";
@@ -2134,6 +2175,17 @@ def am_brcond : Operand<OtherVT> {
21342175
let OperandType = "OPERAND_PCREL";
21352176
}
21362177

2178+
// Conditional branch target. 9-bit immediate. The low two bits of the target
2179+
// offset are implied zero and so are not part of the immediate.
2180+
def am_brcmpcond : Operand<OtherVT> {
2181+
let EncoderMethod = "getCondCompBranchTargetOpValue";
2182+
let DecoderMethod = "DecodePCRelLabel9";
2183+
let PrintMethod = "printAlignedLabel";
2184+
let ParserMatchClass = PCRelLabel9Operand;
2185+
let OperandType = "OPERAND_PCREL";
2186+
}
2187+
2188+
21372189
class BranchCond<bit bit4, string mnemonic>
21382190
: I<(outs), (ins ccode:$cond, am_brcond:$target),
21392191
mnemonic, ".$cond\t$target", "",
@@ -12607,6 +12659,89 @@ class MulAccumCPA<bit isSub, string asm>
1260712659
let Inst{31} = 0b1;
1260812660
}
1260912661

12662+
12663+
//----------------------------------------------------------------------------
12664+
// 2023 Armv9.6 Extensions
12665+
//----------------------------------------------------------------------------
12666+
12667+
//---
12668+
// Compare-and-branch instructions.
12669+
//---
12670+
12671+
class BaseCmpBranchRegister<RegisterClass regtype, bit sf, bits<3> cc,
12672+
bits<2>sz, string asm>
12673+
: I<(outs), (ins regtype:$Rt, regtype:$Rm, am_brcmpcond:$target),
12674+
asm, "\t$Rt, $Rm, $target", "",
12675+
[]>,
12676+
Sched<[WriteBr]> {
12677+
let isBranch = 1;
12678+
let isTerminator = 1;
12679+
12680+
bits<5> Rm;
12681+
bits<5> Rt;
12682+
bits<9> target;
12683+
let Inst{31} = sf;
12684+
let Inst{30-24} = 0b1110100;
12685+
let Inst{23-21} = cc;
12686+
let Inst{20-16} = Rm;
12687+
let Inst{15-14} = sz;
12688+
let Inst{13-5} = target;
12689+
let Inst{4-0} = Rt;
12690+
}
12691+
12692+
multiclass CmpBranchRegister<bits<3> cc, string asm> {
12693+
def Wrr : BaseCmpBranchRegister<GPR32, 0b0, cc, 0b00, asm>;
12694+
def Xrr : BaseCmpBranchRegister<GPR64, 0b1, cc, 0b00, asm>;
12695+
}
12696+
12697+
class BaseCmpBranchImmediate<RegisterClass regtype, bit sf, bits<3> cc,
12698+
Operand imm_ty, string asm>
12699+
: I<(outs), (ins regtype:$Rt, imm_ty:$imm, am_brcmpcond:$target),
12700+
asm, "\t$Rt, $imm, $target", "",
12701+
[]>,
12702+
Sched<[WriteBr]> {
12703+
let isBranch = 1;
12704+
let isTerminator = 1;
12705+
12706+
bits<5> Rt;
12707+
bits<6> imm;
12708+
bits<9> target;
12709+
let Inst{31} = sf;
12710+
let Inst{30-24} = 0b1110101;
12711+
let Inst{23-21} = cc;
12712+
let Inst{20-15} = imm;
12713+
let Inst{14} = 0b0;
12714+
let Inst{13-5} = target;
12715+
let Inst{4-0} = Rt;
12716+
}
12717+
12718+
multiclass CmpBranchImmediate<bits<3> cc, string imm_ty, string asm> {
12719+
def Wri : BaseCmpBranchImmediate<GPR32, 0b0, cc, !cast<Operand>(imm_ty # "_32b"), asm>;
12720+
def Xri : BaseCmpBranchImmediate<GPR64, 0b1, cc, !cast<Operand>(imm_ty # "_64b"), asm>;
12721+
}
12722+
12723+
multiclass CmpBranchImmediateAlias<string mnemonic, string insn, string imm_ty> {
12724+
def : InstAlias<mnemonic # "\t$Rt, $imm, $target",
12725+
(!cast<Instruction>(insn # "Wri") GPR32:$Rt,
12726+
!cast<Operand>(imm_ty # "_32b"):$imm,
12727+
am_brcmpcond:$target), 0>;
12728+
def : InstAlias<mnemonic # "\t$Rt, $imm, $target",
12729+
(!cast<Instruction>(insn # "Xri") GPR64:$Rt,
12730+
!cast<Operand>(imm_ty # "_64b"):$imm,
12731+
am_brcmpcond:$target), 0>;
12732+
}
12733+
12734+
multiclass CmpBranchWRegisterAlias<string mnemonic, string insn> {
12735+
def : InstAlias<mnemonic # "\t$Rt, $Rm, $target",
12736+
(!cast<Instruction>(insn # "Wrr") GPR32:$Rm, GPR32:$Rt, am_brcmpcond:$target), 0>;
12737+
}
12738+
12739+
multiclass CmpBranchRegisterAlias<string mnemonic, string insn> {
12740+
defm : CmpBranchWRegisterAlias<mnemonic, insn>;
12741+
12742+
def : InstAlias<mnemonic # "\t$Rt, $Rm, $target",
12743+
(!cast<Instruction>(insn # "Xrr") GPR64:$Rm, GPR64:$Rt, am_brcmpcond:$target), 0>;
12744+
}
1261012745
//----------------------------------------------------------------------------
1261112746
// Allow the size specifier tokens to be upper case, not just lower.
1261212747
def : TokenAlias<".4B", ".4b">; // Add dot product

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10378,6 +10378,56 @@ defm : PromoteBinaryv8f16Tov4f32<any_fdiv, FDIVv4f32>;
1037810378
defm : PromoteBinaryv8f16Tov4f32<any_fmul, FMULv4f32>;
1037910379
defm : PromoteBinaryv8f16Tov4f32<any_fsub, FSUBv4f32>;
1038010380

10381+
let Predicates = [HasCMPBR] in {
10382+
defm CBGT : CmpBranchRegister<0b000, "cbgt">;
10383+
defm CBGE : CmpBranchRegister<0b001, "cbge">;
10384+
defm CBHI : CmpBranchRegister<0b010, "cbhi">;
10385+
defm CBHS : CmpBranchRegister<0b011, "cbhs">;
10386+
defm CBEQ : CmpBranchRegister<0b110, "cbeq">;
10387+
defm CBNE : CmpBranchRegister<0b111, "cbne">;
10388+
10389+
def CBHGTWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b000, 0b11, "cbhgt">;
10390+
def CBHGEWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b001, 0b11, "cbhge">;
10391+
def CBHHIWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b010, 0b11, "cbhhi">;
10392+
def CBHHSWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b011, 0b11, "cbhhs">;
10393+
def CBHEQWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b110, 0b11, "cbheq">;
10394+
def CBHNEWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b111, 0b11, "cbhne">;
10395+
10396+
def CBBGTWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b000, 0b10, "cbbgt">;
10397+
def CBBGEWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b001, 0b10, "cbbge">;
10398+
def CBBHIWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b010, 0b10, "cbbhi">;
10399+
def CBBHSWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b011, 0b10, "cbbhs">;
10400+
def CBBEQWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b110, 0b10, "cbbeq">;
10401+
def CBBNEWrr : BaseCmpBranchRegister<GPR32, 0b0, 0b111, 0b10, "cbbne">;
10402+
10403+
defm CBGT : CmpBranchImmediate<0b000, "uimm6", "cbgt">;
10404+
defm CBLT : CmpBranchImmediate<0b001, "uimm6", "cblt">;
10405+
defm CBHI : CmpBranchImmediate<0b010, "uimm6", "cbhi">;
10406+
defm CBLO : CmpBranchImmediate<0b011, "uimm6", "cblo">;
10407+
defm CBEQ : CmpBranchImmediate<0b110, "uimm6", "cbeq">;
10408+
defm CBNE : CmpBranchImmediate<0b111, "uimm6", "cbne">;
10409+
10410+
defm : CmpBranchImmediateAlias<"cbge", "CBGT", "uimm6p1">;
10411+
defm : CmpBranchImmediateAlias<"cbhs", "CBHI", "uimm6p1">;
10412+
defm : CmpBranchImmediateAlias<"cble", "CBLT", "uimm6m1">;
10413+
defm : CmpBranchImmediateAlias<"cbls", "CBLO", "uimm6m1">;
10414+
10415+
defm : CmpBranchRegisterAlias<"cble", "CBGE">;
10416+
defm : CmpBranchRegisterAlias<"cblo", "CBHI">;
10417+
defm : CmpBranchRegisterAlias<"cbls", "CBHS">;
10418+
defm : CmpBranchRegisterAlias<"cblt", "CBGT">;
10419+
10420+
defm : CmpBranchWRegisterAlias<"cbble", "CBBGE">;
10421+
defm : CmpBranchWRegisterAlias<"cbblo", "CBBHI">;
10422+
defm : CmpBranchWRegisterAlias<"cbbls", "CBBHS">;
10423+
defm : CmpBranchWRegisterAlias<"cbblt", "CBBGT">;
10424+
10425+
defm : CmpBranchWRegisterAlias<"cbhle", "CBHGE">;
10426+
defm : CmpBranchWRegisterAlias<"cbhlo", "CBHHI">;
10427+
defm : CmpBranchWRegisterAlias<"cbhls", "CBHHS">;
10428+
defm : CmpBranchWRegisterAlias<"cbhlt", "CBHGT">;
10429+
} // HasCMPBR
10430+
1038110431
include "AArch64InstrAtomics.td"
1038210432
include "AArch64SVEInstrInfo.td"
1038310433
include "AArch64SMEInstrInfo.td"

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
286286
ParseStatus tryParseSVEVecLenSpecifier(OperandVector &Operands);
287287
ParseStatus tryParseGPR64x8(OperandVector &Operands);
288288
ParseStatus tryParseImmRange(OperandVector &Operands);
289+
template <int> ParseStatus tryParseAdjImm0_63(OperandVector &Operands);
289290

290291
public:
291292
enum AArch64MatchResultTy {
@@ -2068,6 +2069,20 @@ class AArch64Operand : public MCParsedAsmOperand {
20682069
Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
20692070
}
20702071

2072+
void addPCRelLabel9Operands(MCInst &Inst, unsigned N) const {
2073+
// Branch operands don't encode the low bits, so shift them off
2074+
// here. If it's a label, however, just put it on directly as there's
2075+
// not enough information now to do anything.
2076+
assert(N == 1 && "Invalid number of operands!");
2077+
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
2078+
if (!MCE) {
2079+
addExpr(Inst, getImm());
2080+
return;
2081+
}
2082+
assert(MCE && "Invalid constant immediate operand!");
2083+
Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
2084+
}
2085+
20712086
void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
20722087
// Branch operands don't encode the low bits, so shift them off
20732088
// here. If it's a label, however, just put it on directly as there's
@@ -5913,6 +5928,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
59135928
return Error(Loc, "immediate must be an integer in range [1, 32].");
59145929
case Match_InvalidImm1_64:
59155930
return Error(Loc, "immediate must be an integer in range [1, 64].");
5931+
case Match_InvalidImmM1_62:
5932+
return Error(Loc, "immediate must be an integer in range [-1, 62].");
59165933
case Match_InvalidMemoryIndexedRange2UImm0:
59175934
return Error(Loc, "vector select offset must be the immediate range 0:1.");
59185935
case Match_InvalidMemoryIndexedRange2UImm1:
@@ -6642,6 +6659,7 @@ bool AArch64AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
66426659
case Match_InvalidImm1_16:
66436660
case Match_InvalidImm1_32:
66446661
case Match_InvalidImm1_64:
6662+
case Match_InvalidImmM1_62:
66456663
case Match_InvalidMemoryIndexedRange2UImm0:
66466664
case Match_InvalidMemoryIndexedRange2UImm1:
66476665
case Match_InvalidMemoryIndexedRange2UImm2:
@@ -8093,3 +8111,37 @@ ParseStatus AArch64AsmParser::tryParseImmRange(OperandVector &Operands) {
80938111
AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S, E, getContext()));
80948112
return ParseStatus::Success;
80958113
}
8114+
8115+
template <int Adj>
8116+
ParseStatus AArch64AsmParser::tryParseAdjImm0_63(OperandVector &Operands) {
8117+
SMLoc S = getLoc();
8118+
8119+
parseOptionalToken(AsmToken::Hash);
8120+
bool IsNegative = parseOptionalToken(AsmToken::Minus);
8121+
8122+
if (getTok().isNot(AsmToken::Integer))
8123+
return ParseStatus::NoMatch;
8124+
8125+
const MCExpr *Ex;
8126+
if (getParser().parseExpression(Ex))
8127+
return ParseStatus::NoMatch;
8128+
8129+
int64_t Imm = dyn_cast<MCConstantExpr>(Ex)->getValue();
8130+
if (IsNegative)
8131+
Imm = -Imm;
8132+
8133+
// We want an adjusted immediate in the range [0, 63]. If we don't have one,
8134+
// return a value, which is certain to trigger a error message about invalid
8135+
// immediate range instead of a non-descriptive invalid operand error.
8136+
static_assert(Adj == 1 || Adj == -1, "Unsafe immediate adjustment");
8137+
if (Imm == INT64_MIN || Imm == INT64_MAX || Imm + Adj < 0 || Imm + Adj > 63)
8138+
Imm = -2;
8139+
else
8140+
Imm += Adj;
8141+
8142+
SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
8143+
Operands.push_back(AArch64Operand::CreateImm(
8144+
MCConstantExpr::create(Imm, getContext()), S, E, getContext()));
8145+
8146+
return ParseStatus::Success;
8147+
}

llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
7575
static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
7676
uint64_t Address,
7777
const MCDisassembler *Decoder);
78+
static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm,
79+
uint64_t Address,
80+
const MCDisassembler *Decoder);
7881
static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
7982
uint64_t Address,
8083
const MCDisassembler *Decoder);
@@ -467,6 +470,20 @@ static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
467470
return Success;
468471
}
469472

473+
static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm, uint64_t Addr,
474+
const MCDisassembler *Decoder) {
475+
int64_t ImmVal = Imm;
476+
477+
// Sign-extend 9-bit immediate.
478+
if (ImmVal & (1 << (9 - 1)))
479+
ImmVal |= ~((1LL << 9) - 1);
480+
481+
if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr,
482+
/*IsBranch=*/true, 0, 0, 4))
483+
Inst.addOperand(MCOperand::createImm(ImmVal));
484+
return Success;
485+
}
486+
470487
static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
471488
uint64_t Address,
472489
const MCDisassembler *Decoder) {

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class AArch64AsmBackend : public MCAsmBackend {
6666
{"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
6767
{"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal},
6868
{"fixup_aarch64_movw", 5, 16, 0},
69+
{"fixup_aarch64_pcrel_branch9", 5, 9, PCRelFlagVal},
6970
{"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
7071
{"fixup_aarch64_pcrel_branch16", 5, 16, PCRelFlagVal},
7172
{"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal},
@@ -120,6 +121,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
120121
return 2;
121122

122123
case AArch64::fixup_aarch64_movw:
124+
case AArch64::fixup_aarch64_pcrel_branch9:
123125
case AArch64::fixup_aarch64_pcrel_branch14:
124126
case AArch64::fixup_aarch64_pcrel_branch16:
125127
case AArch64::fixup_aarch64_add_imm12:
@@ -307,6 +309,14 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
307309
}
308310
return Value;
309311
}
312+
case AArch64::fixup_aarch64_pcrel_branch9:
313+
// Signed 11-bit(9bits + 2 shifts) label
314+
if (!isInt<11>(SignedValue))
315+
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
316+
// Low two bits are not encoded (4-byte alignment assumed).
317+
if (Value & 0b11)
318+
Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
319+
return (Value >> 2) & 0x1ff;
310320
case AArch64::fixup_aarch64_pcrel_branch14:
311321
// Signed 16-bit immediate
312322
if (!isInt<16>(SignedValue))
@@ -391,6 +401,7 @@ unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) con
391401
return 8;
392402

393403
case AArch64::fixup_aarch64_movw:
404+
case AArch64::fixup_aarch64_pcrel_branch9:
394405
case AArch64::fixup_aarch64_pcrel_branch14:
395406
case AArch64::fixup_aarch64_pcrel_branch16:
396407
case AArch64::fixup_aarch64_add_imm12:

llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
190190
Ctx.reportError(Fixup.getLoc(),
191191
"relocation of PAC/AUT instructions is not supported");
192192
return ELF::R_AARCH64_NONE;
193+
case AArch64::fixup_aarch64_pcrel_branch9:
194+
Ctx.reportError(
195+
Fixup.getLoc(),
196+
"relocation of compare-and-branch instructions not supported");
197+
return ELF::R_AARCH64_NONE;
193198
case AArch64::fixup_aarch64_pcrel_branch19:
194199
return R_CLS(CONDBR19);
195200
default:

llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ enum Fixups {
4040
// FIXME: comment
4141
fixup_aarch64_movw,
4242

43+
// The high 9 bits of a 11-bit pc-relative immediate.
44+
fixup_aarch64_pcrel_branch9,
45+
4346
// The high 14 bits of a 21-bit pc-relative immediate.
4447
fixup_aarch64_pcrel_branch14,
4548

0 commit comments

Comments
 (0)