Index: llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h @@ -509,9 +509,23 @@ // Corresponds to CV_HREG_e enum. enum class RegisterId : uint16_t { +#define CV_REGISTERS_ALL #define CV_REGISTER(name, value) name = value, #include "CodeViewRegisters.def" #undef CV_REGISTER +#undef CV_REGISTERS_ALL +}; + +// Register Ids are shared between architectures in CodeView. CPUType is needed +// to map register Id to name. +struct CPURegister { + CPURegister() = delete; + CPURegister(CPUType Cpu, codeview::RegisterId Reg) { + this->Cpu = Cpu; + this->Reg = Reg; + } + CPUType Cpu; + RegisterId Reg; }; /// Two-bit value indicating which register is the designated frame pointer Index: llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def +++ llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def @@ -14,8 +14,15 @@ #define CV_REGISTER(name, value) #endif +#if !defined(CV_REGISTERS_ALL) && !defined(CV_REGISTERS_X86) && \ + !defined(CV_REGISTERS_ARM64) +#error Need include at least one register set. +#endif + // This currently only contains the "register subset shared by all processor -// types" (ERR etc.) and the x86 registers. +// types" (ERR etc.) and the x86/arm64 registers. + +#if defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_X86) // Some system headers define macros that conflict with our enums. Every // compiler supported by LLVM has the push_macro and pop_macro pragmas, so use @@ -356,3 +363,197 @@ #pragma pop_macro("CR2") #pragma pop_macro("CR3") #pragma pop_macro("CR4") + +#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_X86) + +#if defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64) + +// ARM64 registers + +CV_REGISTER(ARM64_NOREG, 0) + +// General purpose 32-bit integer registers + +CV_REGISTER(ARM64_W0, 10) +CV_REGISTER(ARM64_W1, 11) +CV_REGISTER(ARM64_W2, 12) +CV_REGISTER(ARM64_W3, 13) +CV_REGISTER(ARM64_W4, 14) +CV_REGISTER(ARM64_W5, 15) +CV_REGISTER(ARM64_W6, 16) +CV_REGISTER(ARM64_W7, 17) +CV_REGISTER(ARM64_W8, 18) +CV_REGISTER(ARM64_W9, 19) +CV_REGISTER(ARM64_W10, 20) +CV_REGISTER(ARM64_W11, 21) +CV_REGISTER(ARM64_W12, 22) +CV_REGISTER(ARM64_W13, 23) +CV_REGISTER(ARM64_W14, 24) +CV_REGISTER(ARM64_W15, 25) +CV_REGISTER(ARM64_W16, 26) +CV_REGISTER(ARM64_W17, 27) +CV_REGISTER(ARM64_W18, 28) +CV_REGISTER(ARM64_W19, 29) +CV_REGISTER(ARM64_W20, 30) +CV_REGISTER(ARM64_W21, 31) +CV_REGISTER(ARM64_W22, 32) +CV_REGISTER(ARM64_W23, 33) +CV_REGISTER(ARM64_W24, 34) +CV_REGISTER(ARM64_W25, 35) +CV_REGISTER(ARM64_W26, 36) +CV_REGISTER(ARM64_W27, 37) +CV_REGISTER(ARM64_W28, 38) +CV_REGISTER(ARM64_W29, 39) +CV_REGISTER(ARM64_W30, 40) +CV_REGISTER(ARM64_WZR, 41) + +// General purpose 64-bit integer registers + +CV_REGISTER(ARM64_X0, 50) +CV_REGISTER(ARM64_X1, 51) +CV_REGISTER(ARM64_X2, 52) +CV_REGISTER(ARM64_X3, 53) +CV_REGISTER(ARM64_X4, 54) +CV_REGISTER(ARM64_X5, 55) +CV_REGISTER(ARM64_X6, 56) +CV_REGISTER(ARM64_X7, 57) +CV_REGISTER(ARM64_X8, 58) +CV_REGISTER(ARM64_X9, 59) +CV_REGISTER(ARM64_X10, 60) +CV_REGISTER(ARM64_X11, 61) +CV_REGISTER(ARM64_X12, 62) +CV_REGISTER(ARM64_X13, 63) +CV_REGISTER(ARM64_X14, 64) +CV_REGISTER(ARM64_X15, 65) +CV_REGISTER(ARM64_X16, 66) +CV_REGISTER(ARM64_X17, 67) +CV_REGISTER(ARM64_X18, 68) +CV_REGISTER(ARM64_X19, 69) +CV_REGISTER(ARM64_X20, 70) +CV_REGISTER(ARM64_X21, 71) +CV_REGISTER(ARM64_X22, 72) +CV_REGISTER(ARM64_X23, 73) +CV_REGISTER(ARM64_X24, 74) +CV_REGISTER(ARM64_X25, 75) +CV_REGISTER(ARM64_X26, 76) +CV_REGISTER(ARM64_X27, 77) +CV_REGISTER(ARM64_X28, 78) +CV_REGISTER(ARM64_FP, 79) +CV_REGISTER(ARM64_LR, 80) +CV_REGISTER(ARM64_SP, 81) +CV_REGISTER(ARM64_ZR, 82) + +// status register + +CV_REGISTER(ARM64_NZCV, 90) + +// 32-bit floating point registers + +CV_REGISTER(ARM64_S0, 100) +CV_REGISTER(ARM64_S1, 101) +CV_REGISTER(ARM64_S2, 102) +CV_REGISTER(ARM64_S3, 103) +CV_REGISTER(ARM64_S4, 104) +CV_REGISTER(ARM64_S5, 105) +CV_REGISTER(ARM64_S6, 106) +CV_REGISTER(ARM64_S7, 107) +CV_REGISTER(ARM64_S8, 108) +CV_REGISTER(ARM64_S9, 109) +CV_REGISTER(ARM64_S10, 110) +CV_REGISTER(ARM64_S11, 111) +CV_REGISTER(ARM64_S12, 112) +CV_REGISTER(ARM64_S13, 113) +CV_REGISTER(ARM64_S14, 114) +CV_REGISTER(ARM64_S15, 115) +CV_REGISTER(ARM64_S16, 116) +CV_REGISTER(ARM64_S17, 117) +CV_REGISTER(ARM64_S18, 118) +CV_REGISTER(ARM64_S19, 119) +CV_REGISTER(ARM64_S20, 120) +CV_REGISTER(ARM64_S21, 121) +CV_REGISTER(ARM64_S22, 122) +CV_REGISTER(ARM64_S23, 123) +CV_REGISTER(ARM64_S24, 124) +CV_REGISTER(ARM64_S25, 125) +CV_REGISTER(ARM64_S26, 126) +CV_REGISTER(ARM64_S27, 127) +CV_REGISTER(ARM64_S28, 128) +CV_REGISTER(ARM64_S29, 129) +CV_REGISTER(ARM64_S30, 130) +CV_REGISTER(ARM64_S31, 131) + +// 64-bit floating point registers + +CV_REGISTER(ARM64_D0, 140) +CV_REGISTER(ARM64_D1, 141) +CV_REGISTER(ARM64_D2, 142) +CV_REGISTER(ARM64_D3, 143) +CV_REGISTER(ARM64_D4, 144) +CV_REGISTER(ARM64_D5, 145) +CV_REGISTER(ARM64_D6, 146) +CV_REGISTER(ARM64_D7, 147) +CV_REGISTER(ARM64_D8, 148) +CV_REGISTER(ARM64_D9, 149) +CV_REGISTER(ARM64_D10, 150) +CV_REGISTER(ARM64_D11, 151) +CV_REGISTER(ARM64_D12, 152) +CV_REGISTER(ARM64_D13, 153) +CV_REGISTER(ARM64_D14, 154) +CV_REGISTER(ARM64_D15, 155) +CV_REGISTER(ARM64_D16, 156) +CV_REGISTER(ARM64_D17, 157) +CV_REGISTER(ARM64_D18, 158) +CV_REGISTER(ARM64_D19, 159) +CV_REGISTER(ARM64_D20, 160) +CV_REGISTER(ARM64_D21, 161) +CV_REGISTER(ARM64_D22, 162) +CV_REGISTER(ARM64_D23, 163) +CV_REGISTER(ARM64_D24, 164) +CV_REGISTER(ARM64_D25, 165) +CV_REGISTER(ARM64_D26, 166) +CV_REGISTER(ARM64_D27, 167) +CV_REGISTER(ARM64_D28, 168) +CV_REGISTER(ARM64_D29, 169) +CV_REGISTER(ARM64_D30, 170) +CV_REGISTER(ARM64_D31, 171) + +// 128-bit SIMD registers + +CV_REGISTER(ARM64_Q0, 180) +CV_REGISTER(ARM64_Q1, 181) +CV_REGISTER(ARM64_Q2, 182) +CV_REGISTER(ARM64_Q3, 183) +CV_REGISTER(ARM64_Q4, 184) +CV_REGISTER(ARM64_Q5, 185) +CV_REGISTER(ARM64_Q6, 186) +CV_REGISTER(ARM64_Q7, 187) +CV_REGISTER(ARM64_Q8, 188) +CV_REGISTER(ARM64_Q9, 189) +CV_REGISTER(ARM64_Q10, 190) +CV_REGISTER(ARM64_Q11, 191) +CV_REGISTER(ARM64_Q12, 192) +CV_REGISTER(ARM64_Q13, 193) +CV_REGISTER(ARM64_Q14, 194) +CV_REGISTER(ARM64_Q15, 195) +CV_REGISTER(ARM64_Q16, 196) +CV_REGISTER(ARM64_Q17, 197) +CV_REGISTER(ARM64_Q18, 198) +CV_REGISTER(ARM64_Q19, 199) +CV_REGISTER(ARM64_Q20, 200) +CV_REGISTER(ARM64_Q21, 201) +CV_REGISTER(ARM64_Q22, 202) +CV_REGISTER(ARM64_Q23, 203) +CV_REGISTER(ARM64_Q24, 204) +CV_REGISTER(ARM64_Q25, 205) +CV_REGISTER(ARM64_Q26, 206) +CV_REGISTER(ARM64_Q27, 207) +CV_REGISTER(ARM64_Q28, 208) +CV_REGISTER(ARM64_Q29, 209) +CV_REGISTER(ARM64_Q30, 210) +CV_REGISTER(ARM64_Q31, 211) + +// Floating point status register + +CV_REGISTER(ARM64_FPSR, 220) + +#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64) Index: llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h @@ -20,7 +20,7 @@ ArrayRef> getSymbolTypeNames(); ArrayRef> getTypeLeafNames(); -ArrayRef> getRegisterNames(); +ArrayRef> getRegisterNames(CPUType Cpu); ArrayRef> getPublicSymFlagNames(); ArrayRef> getProcSymFlagNames(); ArrayRef> getLocalFlagNames(); Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h @@ -27,7 +27,8 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_CallingConv &Conv); raw_ostream &operator<<(raw_ostream &OS, const PDB_BuiltinType &Type); raw_ostream &operator<<(raw_ostream &OS, const PDB_DataKind &Data); -raw_ostream &operator<<(raw_ostream &OS, const codeview::RegisterId &Reg); +raw_ostream &operator<<(raw_ostream &OS, + const llvm::codeview::CPURegister &CpuReg); raw_ostream &operator<<(raw_ostream &OS, const PDB_LocType &Loc); raw_ostream &operator<<(raw_ostream &OS, const codeview::ThunkOrdinal &Thunk); raw_ostream &operator<<(raw_ostream &OS, const PDB_Checksum &Checksum); Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -126,6 +126,7 @@ Am33 = 0x13, Amd64 = 0x8664, Arm = 0x1C0, + Arm64 = 0xaa64, ArmNT = 0x1C4, Ebc = 0xEBC, x86 = 0x14C, Index: llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp @@ -31,10 +31,20 @@ #undef CV_TYPE }; -static const EnumEntry RegisterNames[] = { +static const EnumEntry RegisterNames_X86[] = { +#define CV_REGISTERS_X86 #define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name), #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" #undef CV_REGISTER +#undef CV_REGISTERS_X86 +}; + +static const EnumEntry RegisterNames_ARM64[] = { +#define CV_REGISTERS_ARM64 +#define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name), +#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" +#undef CV_REGISTER +#undef CV_REGISTERS_ARM64 }; static const EnumEntry PublicSymFlagNames[] = { @@ -171,6 +181,7 @@ CV_ENUM_CLASS_ENT(CPUType, ARM_XMAC), CV_ENUM_CLASS_ENT(CPUType, ARM_WMMX), CV_ENUM_CLASS_ENT(CPUType, ARM7), + CV_ENUM_CLASS_ENT(CPUType, ARM64), CV_ENUM_CLASS_ENT(CPUType, Omni), CV_ENUM_CLASS_ENT(CPUType, Ia64), CV_ENUM_CLASS_ENT(CPUType, Ia64_2), @@ -300,8 +311,11 @@ return makeArrayRef(TypeLeafNames); } -ArrayRef> getRegisterNames() { - return makeArrayRef(RegisterNames); +ArrayRef> getRegisterNames(CPUType Cpu) { + if (Cpu == CPUType::ARM64) { + return makeArrayRef(RegisterNames_ARM64); + } + return makeArrayRef(RegisterNames_X86); } ArrayRef> getPublicSymFlagNames() { Index: llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -325,7 +325,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) { W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); W.printBoolean("HasSpilledUDTMember", DefRangeRegisterRel.hasSpilledUDTMember()); W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent()); @@ -339,7 +339,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) { W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName); printLocalVariableAddrRange(DefRangeRegister.Range, DefRangeRegister.getRelocationOffset()); @@ -350,7 +350,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) { W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName); W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent); printLocalVariableAddrRange(DefRangeSubfieldRegister.Range, @@ -403,7 +403,8 @@ FrameCookie.getRelocationOffset(), FrameCookie.CodeOffset, &LinkageName); } - W.printEnum("Register", uint16_t(FrameCookie.Register), getRegisterNames()); + W.printEnum("Register", uint16_t(FrameCookie.Register), + getRegisterNames(CompilationCPUType)); W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind), getFrameCookieKindNames()); W.printHex("Flags", FrameCookie.Flags); @@ -424,10 +425,10 @@ getFrameProcSymFlagNames()); W.printEnum("LocalFramePtrReg", uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); W.printEnum("ParamFramePtrReg", uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); return Error::success(); } @@ -505,7 +506,8 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, RegisterSym &Register) { printTypeIndex("Type", Register.Index); - W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames()); + W.printEnum("Seg", uint16_t(Register.Register), + getRegisterNames(CompilationCPUType)); W.printString("Name", Register.Name); return Error::success(); } @@ -599,7 +601,8 @@ RegRelativeSym &RegRel) { W.printHex("Offset", RegRel.Offset); printTypeIndex("Type", RegRel.Type); - W.printEnum("Register", uint16_t(RegRel.Register), getRegisterNames()); + W.printEnum("Register", uint16_t(RegRel.Register), + getRegisterNames(CompilationCPUType)); W.printString("VarName", RegRel.Name); return Error::success(); } Index: llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp +++ llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp @@ -117,13 +117,37 @@ } raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, - const codeview::RegisterId &Reg) { - switch (Reg) { -#define CV_REGISTER(name, val) case codeview::RegisterId::name: OS << #name; return OS; + const llvm::codeview::CPURegister &CpuReg) { + if (CpuReg.Cpu == llvm::codeview::CPUType::ARM64) { + switch (CpuReg.Reg) { +#define CV_REGISTERS_ARM64 +#define CV_REGISTER(name, val) \ + case codeview::RegisterId::name: \ + OS << #name; \ + return OS; #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" #undef CV_REGISTER +#undef CV_REGISTERS_ARM64 + + default: + break; + } + } else { + switch (CpuReg.Reg) { +#define CV_REGISTERS_X86 +#define CV_REGISTER(name, val) \ + case codeview::RegisterId::name: \ + OS << #name; \ + return OS; +#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" +#undef CV_REGISTER +#undef CV_REGISTERS_X86 + + default: + break; + } } - OS << static_cast(Reg); + OS << static_cast(CpuReg.Reg); return OS; } Index: llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp =================================================================== --- llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp +++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp @@ -147,7 +147,7 @@ } void ScalarEnumerationTraits::enumeration(IO &io, RegisterId &Reg) { - auto RegNames = getRegisterNames(); + auto RegNames = getRegisterNames(CPUType::X64); for (const auto &E : RegNames) { io.enumCase(Reg, E.Name.str().c_str(), static_cast(E.Value)); } Index: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp +++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp @@ -17,6 +17,7 @@ #include "MCTargetDesc/AArch64AddressingModes.h" #include "MCTargetDesc/AArch64InstPrinter.h" #include "TargetInfo/AArch64TargetInfo.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCInstrAnalysis.h" @@ -56,11 +57,177 @@ } void AArch64_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) { - for (unsigned Reg = AArch64::NoRegister + 1; - Reg < AArch64::NUM_TARGET_REGS; ++Reg) { - unsigned CV = MRI->getEncodingValue(Reg); - MRI->mapLLVMRegToCVReg(Reg, CV); - } + // Mapping from CodeView to MC register id. + static const struct { + codeview::RegisterId CVReg; + MCPhysReg Reg; + } RegMap[] = { + {codeview::RegisterId::ARM64_W0, AArch64::W0}, + {codeview::RegisterId::ARM64_W1, AArch64::W1}, + {codeview::RegisterId::ARM64_W2, AArch64::W2}, + {codeview::RegisterId::ARM64_W3, AArch64::W3}, + {codeview::RegisterId::ARM64_W4, AArch64::W4}, + {codeview::RegisterId::ARM64_W5, AArch64::W5}, + {codeview::RegisterId::ARM64_W6, AArch64::W6}, + {codeview::RegisterId::ARM64_W7, AArch64::W7}, + {codeview::RegisterId::ARM64_W8, AArch64::W8}, + {codeview::RegisterId::ARM64_W9, AArch64::W9}, + {codeview::RegisterId::ARM64_W10, AArch64::W10}, + {codeview::RegisterId::ARM64_W11, AArch64::W11}, + {codeview::RegisterId::ARM64_W12, AArch64::W12}, + {codeview::RegisterId::ARM64_W13, AArch64::W13}, + {codeview::RegisterId::ARM64_W14, AArch64::W14}, + {codeview::RegisterId::ARM64_W15, AArch64::W15}, + {codeview::RegisterId::ARM64_W16, AArch64::W16}, + {codeview::RegisterId::ARM64_W17, AArch64::W17}, + {codeview::RegisterId::ARM64_W18, AArch64::W18}, + {codeview::RegisterId::ARM64_W19, AArch64::W19}, + {codeview::RegisterId::ARM64_W20, AArch64::W20}, + {codeview::RegisterId::ARM64_W21, AArch64::W21}, + {codeview::RegisterId::ARM64_W22, AArch64::W22}, + {codeview::RegisterId::ARM64_W23, AArch64::W23}, + {codeview::RegisterId::ARM64_W24, AArch64::W24}, + {codeview::RegisterId::ARM64_W25, AArch64::W25}, + {codeview::RegisterId::ARM64_W26, AArch64::W26}, + {codeview::RegisterId::ARM64_W27, AArch64::W27}, + {codeview::RegisterId::ARM64_W28, AArch64::W28}, + {codeview::RegisterId::ARM64_W29, AArch64::W29}, + {codeview::RegisterId::ARM64_W30, AArch64::W30}, + {codeview::RegisterId::ARM64_WZR, AArch64::WZR}, + {codeview::RegisterId::ARM64_X0, AArch64::X0}, + {codeview::RegisterId::ARM64_X1, AArch64::X1}, + {codeview::RegisterId::ARM64_X2, AArch64::X2}, + {codeview::RegisterId::ARM64_X3, AArch64::X3}, + {codeview::RegisterId::ARM64_X4, AArch64::X4}, + {codeview::RegisterId::ARM64_X5, AArch64::X5}, + {codeview::RegisterId::ARM64_X6, AArch64::X6}, + {codeview::RegisterId::ARM64_X7, AArch64::X7}, + {codeview::RegisterId::ARM64_X8, AArch64::X8}, + {codeview::RegisterId::ARM64_X9, AArch64::X9}, + {codeview::RegisterId::ARM64_X10, AArch64::X10}, + {codeview::RegisterId::ARM64_X11, AArch64::X11}, + {codeview::RegisterId::ARM64_X12, AArch64::X12}, + {codeview::RegisterId::ARM64_X13, AArch64::X13}, + {codeview::RegisterId::ARM64_X14, AArch64::X14}, + {codeview::RegisterId::ARM64_X15, AArch64::X15}, + {codeview::RegisterId::ARM64_X16, AArch64::X16}, + {codeview::RegisterId::ARM64_X17, AArch64::X17}, + {codeview::RegisterId::ARM64_X18, AArch64::X18}, + {codeview::RegisterId::ARM64_X19, AArch64::X19}, + {codeview::RegisterId::ARM64_X20, AArch64::X20}, + {codeview::RegisterId::ARM64_X21, AArch64::X21}, + {codeview::RegisterId::ARM64_X22, AArch64::X22}, + {codeview::RegisterId::ARM64_X23, AArch64::X23}, + {codeview::RegisterId::ARM64_X24, AArch64::X24}, + {codeview::RegisterId::ARM64_X25, AArch64::X25}, + {codeview::RegisterId::ARM64_X26, AArch64::X26}, + {codeview::RegisterId::ARM64_X27, AArch64::X27}, + {codeview::RegisterId::ARM64_X28, AArch64::X28}, + {codeview::RegisterId::ARM64_FP, AArch64::FP}, + {codeview::RegisterId::ARM64_LR, AArch64::LR}, + {codeview::RegisterId::ARM64_SP, AArch64::SP}, + {codeview::RegisterId::ARM64_ZR, AArch64::XZR}, + {codeview::RegisterId::ARM64_NZCV, AArch64::NZCV}, + {codeview::RegisterId::ARM64_S0, AArch64::S0}, + {codeview::RegisterId::ARM64_S1, AArch64::S1}, + {codeview::RegisterId::ARM64_S2, AArch64::S2}, + {codeview::RegisterId::ARM64_S3, AArch64::S3}, + {codeview::RegisterId::ARM64_S4, AArch64::S4}, + {codeview::RegisterId::ARM64_S5, AArch64::S5}, + {codeview::RegisterId::ARM64_S6, AArch64::S6}, + {codeview::RegisterId::ARM64_S7, AArch64::S7}, + {codeview::RegisterId::ARM64_S8, AArch64::S8}, + {codeview::RegisterId::ARM64_S9, AArch64::S9}, + {codeview::RegisterId::ARM64_S10, AArch64::S10}, + {codeview::RegisterId::ARM64_S11, AArch64::S11}, + {codeview::RegisterId::ARM64_S12, AArch64::S12}, + {codeview::RegisterId::ARM64_S13, AArch64::S13}, + {codeview::RegisterId::ARM64_S14, AArch64::S14}, + {codeview::RegisterId::ARM64_S15, AArch64::S15}, + {codeview::RegisterId::ARM64_S16, AArch64::S16}, + {codeview::RegisterId::ARM64_S17, AArch64::S17}, + {codeview::RegisterId::ARM64_S18, AArch64::S18}, + {codeview::RegisterId::ARM64_S19, AArch64::S19}, + {codeview::RegisterId::ARM64_S20, AArch64::S20}, + {codeview::RegisterId::ARM64_S21, AArch64::S21}, + {codeview::RegisterId::ARM64_S22, AArch64::S22}, + {codeview::RegisterId::ARM64_S23, AArch64::S23}, + {codeview::RegisterId::ARM64_S24, AArch64::S24}, + {codeview::RegisterId::ARM64_S25, AArch64::S25}, + {codeview::RegisterId::ARM64_S26, AArch64::S26}, + {codeview::RegisterId::ARM64_S27, AArch64::S27}, + {codeview::RegisterId::ARM64_S28, AArch64::S28}, + {codeview::RegisterId::ARM64_S29, AArch64::S29}, + {codeview::RegisterId::ARM64_S30, AArch64::S30}, + {codeview::RegisterId::ARM64_S31, AArch64::S31}, + {codeview::RegisterId::ARM64_D0, AArch64::D0}, + {codeview::RegisterId::ARM64_D1, AArch64::D1}, + {codeview::RegisterId::ARM64_D2, AArch64::D2}, + {codeview::RegisterId::ARM64_D3, AArch64::D3}, + {codeview::RegisterId::ARM64_D4, AArch64::D4}, + {codeview::RegisterId::ARM64_D5, AArch64::D5}, + {codeview::RegisterId::ARM64_D6, AArch64::D6}, + {codeview::RegisterId::ARM64_D7, AArch64::D7}, + {codeview::RegisterId::ARM64_D8, AArch64::D8}, + {codeview::RegisterId::ARM64_D9, AArch64::D9}, + {codeview::RegisterId::ARM64_D10, AArch64::D10}, + {codeview::RegisterId::ARM64_D11, AArch64::D11}, + {codeview::RegisterId::ARM64_D12, AArch64::D12}, + {codeview::RegisterId::ARM64_D13, AArch64::D13}, + {codeview::RegisterId::ARM64_D14, AArch64::D14}, + {codeview::RegisterId::ARM64_D15, AArch64::D15}, + {codeview::RegisterId::ARM64_D16, AArch64::D16}, + {codeview::RegisterId::ARM64_D17, AArch64::D17}, + {codeview::RegisterId::ARM64_D18, AArch64::D18}, + {codeview::RegisterId::ARM64_D19, AArch64::D19}, + {codeview::RegisterId::ARM64_D20, AArch64::D20}, + {codeview::RegisterId::ARM64_D21, AArch64::D21}, + {codeview::RegisterId::ARM64_D22, AArch64::D22}, + {codeview::RegisterId::ARM64_D23, AArch64::D23}, + {codeview::RegisterId::ARM64_D24, AArch64::D24}, + {codeview::RegisterId::ARM64_D25, AArch64::D25}, + {codeview::RegisterId::ARM64_D26, AArch64::D26}, + {codeview::RegisterId::ARM64_D27, AArch64::D27}, + {codeview::RegisterId::ARM64_D28, AArch64::D28}, + {codeview::RegisterId::ARM64_D29, AArch64::D29}, + {codeview::RegisterId::ARM64_D30, AArch64::D30}, + {codeview::RegisterId::ARM64_D31, AArch64::D31}, + {codeview::RegisterId::ARM64_Q0, AArch64::Q0}, + {codeview::RegisterId::ARM64_Q1, AArch64::Q1}, + {codeview::RegisterId::ARM64_Q2, AArch64::Q2}, + {codeview::RegisterId::ARM64_Q3, AArch64::Q3}, + {codeview::RegisterId::ARM64_Q4, AArch64::Q4}, + {codeview::RegisterId::ARM64_Q5, AArch64::Q5}, + {codeview::RegisterId::ARM64_Q6, AArch64::Q6}, + {codeview::RegisterId::ARM64_Q7, AArch64::Q7}, + {codeview::RegisterId::ARM64_Q8, AArch64::Q8}, + {codeview::RegisterId::ARM64_Q9, AArch64::Q9}, + {codeview::RegisterId::ARM64_Q10, AArch64::Q10}, + {codeview::RegisterId::ARM64_Q11, AArch64::Q11}, + {codeview::RegisterId::ARM64_Q12, AArch64::Q12}, + {codeview::RegisterId::ARM64_Q13, AArch64::Q13}, + {codeview::RegisterId::ARM64_Q14, AArch64::Q14}, + {codeview::RegisterId::ARM64_Q15, AArch64::Q15}, + {codeview::RegisterId::ARM64_Q16, AArch64::Q16}, + {codeview::RegisterId::ARM64_Q17, AArch64::Q17}, + {codeview::RegisterId::ARM64_Q18, AArch64::Q18}, + {codeview::RegisterId::ARM64_Q19, AArch64::Q19}, + {codeview::RegisterId::ARM64_Q20, AArch64::Q20}, + {codeview::RegisterId::ARM64_Q21, AArch64::Q21}, + {codeview::RegisterId::ARM64_Q22, AArch64::Q22}, + {codeview::RegisterId::ARM64_Q23, AArch64::Q23}, + {codeview::RegisterId::ARM64_Q24, AArch64::Q24}, + {codeview::RegisterId::ARM64_Q25, AArch64::Q25}, + {codeview::RegisterId::ARM64_Q26, AArch64::Q26}, + {codeview::RegisterId::ARM64_Q27, AArch64::Q27}, + {codeview::RegisterId::ARM64_Q28, AArch64::Q28}, + {codeview::RegisterId::ARM64_Q29, AArch64::Q29}, + {codeview::RegisterId::ARM64_Q30, AArch64::Q30}, + {codeview::RegisterId::ARM64_Q31, AArch64::Q31}, + + }; + for (unsigned I = 0; I < array_lengthof(RegMap); ++I) + MRI->mapLLVMRegToCVReg(RegMap[I].Reg, static_cast(RegMap[I].CVReg)); } static MCRegisterInfo *createAArch64MCRegisterInfo(const Triple &Triple) { Index: llvm/trunk/test/DebugInfo/COFF/register-variables-arm64.ll =================================================================== --- llvm/trunk/test/DebugInfo/COFF/register-variables-arm64.ll +++ llvm/trunk/test/DebugInfo/COFF/register-variables-arm64.ll @@ -0,0 +1,149 @@ +; RUN: llc < %s -filetype=obj | llvm-readobj --codeview - | FileCheck %s --check-prefix=OBJ + +; Generated from: +; volatile int x; +; int getint(void); +; void putint(int); +; static inline int inlineinc(int a) { +; int b = a + 1; +; ++x; +; return b; +; } +; void f(int p) { +; if (p) { +; int a = getint(); +; int b = inlineinc(a); +; putint(b); +; } else { +; int c = getint(); +; putint(c); +; } +; } + + +; OBJ: DefRangeRegisterRelSym { +; OBJ: Kind: S_DEFRANGE_REGISTER_REL (0x1145) +; OBJ: BaseRegister: ARM64_SP (0x51) +; OBJ: HasSpilledUDTMember: No +; OBJ: OffsetInParent: 0 +; OBJ: BasePointerOffset: 12 +; OBJ: LocalVariableAddrRange { +; OBJ: OffsetStart: .text+0x10 +; OBJ: ISectStart: 0x0 +; OBJ: Range: 0x2C +; OBJ: } +; OBJ: } + +; ModuleID = 't.cpp' +source_filename = "test/DebugInfo/COFF/register-variables-arm64.ll" +target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128" +target triple = "arm64-unknown-windows-msvc19.16.27023" + +@x = common dso_local global i32 0, align 4, !dbg !0 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @f(i32 %p) #0 !dbg !12 { +entry: + %p.addr = alloca i32, align 4 + %a = alloca i32, align 4 + %b = alloca i32, align 4 + %c = alloca i32, align 4 + store i32 %p, i32* %p.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %p.addr, metadata !15, metadata !DIExpression()), !dbg !16 + %0 = load i32, i32* %p.addr, align 4, !dbg !17 + %tobool = icmp ne i32 %0, 0, !dbg !17 + br i1 %tobool, label %if.then, label %if.else, !dbg !17 + +if.then: ; preds = %entry + call void @llvm.dbg.declare(metadata i32* %a, metadata !18, metadata !DIExpression()), !dbg !21 + %call = call i32 @getint(), !dbg !21 + store i32 %call, i32* %a, align 4, !dbg !21 + call void @llvm.dbg.declare(metadata i32* %b, metadata !22, metadata !DIExpression()), !dbg !23 + %1 = load i32, i32* %a, align 4, !dbg !23 + %call1 = call i32 @inlineinc(i32 %1), !dbg !23 + store i32 %call1, i32* %b, align 4, !dbg !23 + %2 = load i32, i32* %b, align 4, !dbg !24 + call void @putint(i32 %2), !dbg !24 + br label %if.end, !dbg !25 + +if.else: ; preds = %entry + call void @llvm.dbg.declare(metadata i32* %c, metadata !26, metadata !DIExpression()), !dbg !28 + %call2 = call i32 @getint(), !dbg !28 + store i32 %call2, i32* %c, align 4, !dbg !28 + %3 = load i32, i32* %c, align 4, !dbg !29 + call void @putint(i32 %3), !dbg !29 + br label %if.end, !dbg !30 + +if.end: ; preds = %if.else, %if.then + ret void, !dbg !31 +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +declare dso_local i32 @getint() #2 + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @inlineinc(i32 %a) #0 !dbg !32 { +entry: + %a.addr = alloca i32, align 4 + %b = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !35, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32* %b, metadata !37, metadata !DIExpression()), !dbg !38 + %0 = load i32, i32* %a.addr, align 4, !dbg !38 + %add = add nsw i32 %0, 1, !dbg !38 + store i32 %add, i32* %b, align 4, !dbg !38 + %1 = load volatile i32, i32* @x, align 4, !dbg !39 + %inc = add nsw i32 %1, 1, !dbg !39 + store volatile i32 %inc, i32* @x, align 4, !dbg !39 + %2 = load i32, i32* %b, align 4, !dbg !40 + ret i32 %2, !dbg !40 +} + +declare dso_local void @putint(i32) #2 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!8, !9, !10} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "x", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 9.0.0 (trunk 361867) (llvm/trunk 361866)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "S:\5CLLVM\5Csvn\5Csbr\5Cbin", checksumkind: CSK_MD5, checksum: "734c448e95a6204a439a847ed063e5ce") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !7) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"CodeView", i32 1} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 2} +!11 = !{!"clang version 9.0.0 (trunk 361867) (llvm/trunk 361866)"} +!12 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 9, type: !13, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !4) +!13 = !DISubroutineType(types: !14) +!14 = !{null, !7} +!15 = !DILocalVariable(name: "p", arg: 1, scope: !12, file: !3, line: 9, type: !7) +!16 = !DILocation(line: 9, scope: !12) +!17 = !DILocation(line: 10, scope: !12) +!18 = !DILocalVariable(name: "a", scope: !19, file: !3, line: 11, type: !7) +!19 = distinct !DILexicalBlock(scope: !20, file: !3, line: 10) +!20 = distinct !DILexicalBlock(scope: !12, file: !3, line: 10) +!21 = !DILocation(line: 11, scope: !19) +!22 = !DILocalVariable(name: "b", scope: !19, file: !3, line: 12, type: !7) +!23 = !DILocation(line: 12, scope: !19) +!24 = !DILocation(line: 13, scope: !19) +!25 = !DILocation(line: 14, scope: !19) +!26 = !DILocalVariable(name: "c", scope: !27, file: !3, line: 15, type: !7) +!27 = distinct !DILexicalBlock(scope: !20, file: !3, line: 14) +!28 = !DILocation(line: 15, scope: !27) +!29 = !DILocation(line: 16, scope: !27) +!30 = !DILocation(line: 17, scope: !27) +!31 = !DILocation(line: 18, scope: !12) +!32 = distinct !DISubprogram(name: "inlineinc", scope: !3, file: !3, line: 4, type: !33, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2, retainedNodes: !4) +!33 = !DISubroutineType(types: !34) +!34 = !{!7, !7} +!35 = !DILocalVariable(name: "a", arg: 1, scope: !32, file: !3, line: 4, type: !7) +!36 = !DILocation(line: 4, scope: !32) +!37 = !DILocalVariable(name: "b", scope: !32, file: !3, line: 5, type: !7) +!38 = !DILocation(line: 5, scope: !32) +!39 = !DILocation(line: 6, scope: !32) +!40 = !DILocation(line: 7, scope: !32) Index: llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp +++ llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp @@ -287,21 +287,39 @@ return formatUnknownEnum(Kind); } -static std::string formatRegisterId(RegisterId Id) { - switch (Id) { +static std::string formatRegisterId(RegisterId Id, CPUType Cpu) { + if (Cpu == CPUType::ARM64) { + switch (Id) { +#define CV_REGISTERS_ARM64 #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name) #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" #undef CV_REGISTER +#undef CV_REGISTERS_ARM64 + + default: + break; + } + } else { + switch (Id) { +#define CV_REGISTERS_X86 +#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name) +#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" +#undef CV_REGISTER +#undef CV_REGISTERS_X86 + + default: + break; + } } return formatUnknownEnum(Id); } -static std::string formatRegisterId(uint16_t Reg16) { - return formatRegisterId(RegisterId(Reg16)); +static std::string formatRegisterId(uint16_t Reg16, CPUType Cpu) { + return formatRegisterId(RegisterId(Reg16), Cpu); } -static std::string formatRegisterId(ulittle16_t &Reg16) { - return formatRegisterId(uint16_t(Reg16)); +static std::string formatRegisterId(ulittle16_t &Reg16, CPUType Cpu) { + return formatRegisterId(uint16_t(Reg16), Cpu); } static std::string formatRange(LocalVariableAddrRange Range) { @@ -562,7 +580,7 @@ AutoIndent Indent(P, 7); P.formatLine("register = {0}, offset = {1}, offset in parent = {2}, has " "spilled udt = {3}", - formatRegisterId(Def.Hdr.Register), + formatRegisterId(Def.Hdr.Register, CompilationCPU), int32_t(Def.Hdr.BasePointerOffset), Def.offsetInParent(), Def.hasSpilledUDTMember()); P.formatLine("range = {0}, gaps = {1}", formatRange(Def.Range), @@ -575,7 +593,7 @@ AutoIndent Indent(P, 7); P.formatLine("register = {0}, may have no name = {1}, range start = " "{2}, length = {3}", - formatRegisterId(DefRangeRegister.Hdr.Register), + formatRegisterId(DefRangeRegister.Hdr.Register, CompilationCPU), bool(DefRangeRegister.Hdr.MayHaveNoName), formatSegmentOffset(DefRangeRegister.Range.ISectStart, DefRangeRegister.Range.OffsetStart), @@ -590,7 +608,7 @@ AutoIndent Indent(P, 7); bool NoName = !!(Def.Hdr.MayHaveNoName == 0); P.formatLine("register = {0}, may have no name = {1}, offset in parent = {2}", - formatRegisterId(Def.Hdr.Register), NoName, + formatRegisterId(Def.Hdr.Register, CompilationCPU), NoName, uint32_t(Def.Hdr.OffsetInParent)); P.formatLine("range = {0}, gaps = {1}", formatRange(Def.Range), formatGaps(P.getIndentLevel() + 9, Def.Gaps)); @@ -617,7 +635,7 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameCookieSym &FC) { AutoIndent Indent(P, 7); P.formatLine("code offset = {0}, Register = {1}, kind = {2}, flags = {3}", - FC.CodeOffset, formatRegisterId(FC.Register), + FC.CodeOffset, formatRegisterId(FC.Register, CompilationCPU), formatCookieKind(FC.CookieKind), FC.Flags); return Error::success(); } @@ -631,9 +649,10 @@ FP.BytesOfCalleeSavedRegisters, formatSegmentOffset(FP.SectionIdOfExceptionHandler, FP.OffsetOfExceptionHandler)); - P.formatLine("local fp reg = {0}, param fp reg = {1}", - formatRegisterId(FP.getLocalFramePtrReg(CompilationCPU)), - formatRegisterId(FP.getParamFramePtrReg(CompilationCPU))); + P.formatLine( + "local fp reg = {0}, param fp reg = {1}", + formatRegisterId(FP.getLocalFramePtrReg(CompilationCPU), CompilationCPU), + formatRegisterId(FP.getParamFramePtrReg(CompilationCPU), CompilationCPU)); P.formatLine("flags = {0}", formatFrameProcedureOptions(P.getIndentLevel() + 9, FP.Flags)); return Error::success(); @@ -741,7 +760,8 @@ P.format(" `{0}`", Register.Name); AutoIndent Indent(P, 7); P.formatLine("register = {0}, type = {1}", - formatRegisterId(Register.Register), typeIndex(Register.Index)); + formatRegisterId(Register.Register, CompilationCPU), + typeIndex(Register.Index)); return Error::success(); } @@ -829,9 +849,9 @@ RegRelativeSym &RegRel) { P.format(" `{0}`", RegRel.Name); AutoIndent Indent(P, 7); - P.formatLine("type = {0}, register = {1}, offset = {2}", - typeIndex(RegRel.Type), formatRegisterId(RegRel.Register), - RegRel.Offset); + P.formatLine( + "type = {0}, register = {1}, offset = {2}", typeIndex(RegRel.Type), + formatRegisterId(RegRel.Register, CompilationCPU), RegRel.Offset); return Error::success(); } Index: llvm/trunk/tools/llvm-pdbutil/PdbYaml.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/PdbYaml.cpp +++ llvm/trunk/tools/llvm-pdbutil/PdbYaml.cpp @@ -50,6 +50,7 @@ io.enumCase(Value, "SH3DSP", PDB_Machine::SH3DSP); io.enumCase(Value, "Thumb", PDB_Machine::Thumb); io.enumCase(Value, "WceMipsV2", PDB_Machine::WceMipsV2); + io.enumCase(Value, "Arm64", PDB_Machine::Arm64); } }; Index: llvm/trunk/tools/llvm-pdbutil/PrettyFunctionDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/PrettyFunctionDumper.cpp +++ llvm/trunk/tools/llvm-pdbutil/PrettyFunctionDumper.cpp @@ -138,7 +138,8 @@ if (Symbol.hasFramePointer()) { WithColor(Printer, PDB_ColorItem::Register).get() - << Symbol.getLocalBasePointerRegisterId(); + << CPURegister{Symbol.getRawSymbol().getPlatform(), + Symbol.getLocalBasePointerRegisterId()}; } else { WithColor(Printer, PDB_ColorItem::Register).get() << "FPO"; }