/// Print operand target flags.
static void printTargetFlags(raw_ostream& OS, const MachineOperand &Op);
+ /// Print a MCSymbol as an operand.
+ static void printSymbol(raw_ostream &OS, MCSymbol &Sym);
+
/// Print the MachineOperand to \p os.
/// Providing a valid \p TRI and \p IntrinsicInfo results in a more
/// target-specific printing. If \p TRI and \p IntrinsicInfo are null, the
.Case("debug-location", MIToken::kw_debug_location)
.Case("same_value", MIToken::kw_cfi_same_value)
.Case("offset", MIToken::kw_cfi_offset)
+ .Case("rel_offset", MIToken::kw_cfi_rel_offset)
.Case("def_cfa_register", MIToken::kw_cfi_def_cfa_register)
.Case("def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
+ .Case("adjust_cfa_offset", MIToken::kw_cfi_adjust_cfa_offset)
+ .Case("escape", MIToken::kw_cfi_escape)
.Case("def_cfa", MIToken::kw_cfi_def_cfa)
+ .Case("remember_state", MIToken::kw_cfi_remember_state)
.Case("restore", MIToken::kw_cfi_restore)
+ .Case("restore_state", MIToken::kw_cfi_restore_state)
+ .Case("undefined", MIToken::kw_cfi_undefined)
+ .Case("register", MIToken::kw_cfi_register)
+ .Case("window_save", MIToken::kw_cfi_window_save)
.Case("blockaddress", MIToken::kw_blockaddress)
.Case("intrinsic", MIToken::kw_intrinsic)
.Case("target-index", MIToken::kw_target_index)
kw_debug_location,
kw_cfi_same_value,
kw_cfi_offset,
+ kw_cfi_rel_offset,
kw_cfi_def_cfa_register,
kw_cfi_def_cfa_offset,
+ kw_cfi_adjust_cfa_offset,
+ kw_cfi_escape,
kw_cfi_def_cfa,
+ kw_cfi_register,
+ kw_cfi_remember_state,
kw_cfi_restore,
+ kw_cfi_restore_state,
+ kw_cfi_undefined,
+ kw_cfi_window_save,
kw_blockaddress,
kw_intrinsic,
kw_target_index,
bool parseMetadataOperand(MachineOperand &Dest);
bool parseCFIOffset(int &Offset);
bool parseCFIRegister(unsigned &Reg);
+ bool parseCFIEscapeValues(std::string& Values);
bool parseCFIOperand(MachineOperand &Dest);
bool parseIRBlock(BasicBlock *&BB, const Function &F);
bool parseBlockAddressOperand(MachineOperand &Dest);
return false;
}
+bool MIParser::parseCFIEscapeValues(std::string &Values) {
+ do {
+ if (Token.isNot(MIToken::HexLiteral))
+ return error("expected a hexadecimal literal");
+ unsigned Value;
+ if (getUnsigned(Value))
+ return true;
+ if (Value > UINT8_MAX)
+ return error("expected a 8-bit integer (too large)");
+ Values.push_back(static_cast<uint8_t>(Value));
+ lex();
+ } while (consumeIfPresent(MIToken::comma));
+ return false;
+}
+
bool MIParser::parseCFIOperand(MachineOperand &Dest) {
auto Kind = Token.kind();
lex();
CFIIndex =
MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
break;
+ case MIToken::kw_cfi_rel_offset:
+ if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
+ parseCFIOffset(Offset))
+ return true;
+ CFIIndex = MF.addFrameInst(
+ MCCFIInstruction::createRelOffset(nullptr, Reg, Offset));
+ break;
case MIToken::kw_cfi_def_cfa_register:
if (parseCFIRegister(Reg))
return true;
CFIIndex = MF.addFrameInst(
MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
break;
+ case MIToken::kw_cfi_adjust_cfa_offset:
+ if (parseCFIOffset(Offset))
+ return true;
+ CFIIndex = MF.addFrameInst(
+ MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset));
+ break;
case MIToken::kw_cfi_def_cfa:
if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
parseCFIOffset(Offset))
CFIIndex =
MF.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset));
break;
+ case MIToken::kw_cfi_remember_state:
+ CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr));
+ break;
case MIToken::kw_cfi_restore:
if (parseCFIRegister(Reg))
return true;
CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
break;
+ case MIToken::kw_cfi_restore_state:
+ CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr));
+ break;
+ case MIToken::kw_cfi_undefined:
+ if (parseCFIRegister(Reg))
+ return true;
+ CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg));
+ break;
+ case MIToken::kw_cfi_register: {
+ unsigned Reg2;
+ if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
+ parseCFIRegister(Reg2))
+ return true;
+ CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2));
+ break;
+ }
+ case MIToken::kw_cfi_window_save:
+ CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
+ break;
+ case MIToken::kw_cfi_escape: {
+ std::string Values;
+ if (parseCFIEscapeValues(Values))
+ return true;
+ CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values));
+ break;
+ }
default:
// TODO: Parse the other CFI operands.
llvm_unreachable("The current token should be a cfi operand");
return parseMetadataOperand(Dest);
case MIToken::kw_cfi_same_value:
case MIToken::kw_cfi_offset:
+ case MIToken::kw_cfi_rel_offset:
case MIToken::kw_cfi_def_cfa_register:
case MIToken::kw_cfi_def_cfa_offset:
+ case MIToken::kw_cfi_adjust_cfa_offset:
+ case MIToken::kw_cfi_escape:
case MIToken::kw_cfi_def_cfa:
+ case MIToken::kw_cfi_register:
+ case MIToken::kw_cfi_remember_state:
case MIToken::kw_cfi_restore:
+ case MIToken::kw_cfi_restore_state:
+ case MIToken::kw_cfi_undefined:
+ case MIToken::kw_cfi_window_save:
return parseCFIOperand(Dest);
case MIToken::kw_blockaddress:
return parseBlockAddressOperand(Dest);
switch (CFI.getOperation()) {
case MCCFIInstruction::OpSameValue:
OS << "same_value ";
- if (CFI.getLabel())
- OS << "<mcsymbol> ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
printCFIRegister(CFI.getRegister(), OS, TRI);
break;
+ case MCCFIInstruction::OpRememberState:
+ OS << "remember_state ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
+ break;
+ case MCCFIInstruction::OpRestoreState:
+ OS << "restore_state ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
+ break;
case MCCFIInstruction::OpOffset:
OS << "offset ";
- if (CFI.getLabel())
- OS << "<mcsymbol> ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
printCFIRegister(CFI.getRegister(), OS, TRI);
OS << ", " << CFI.getOffset();
break;
case MCCFIInstruction::OpDefCfaRegister:
OS << "def_cfa_register ";
- if (CFI.getLabel())
- OS << "<mcsymbol> ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
printCFIRegister(CFI.getRegister(), OS, TRI);
break;
case MCCFIInstruction::OpDefCfaOffset:
OS << "def_cfa_offset ";
- if (CFI.getLabel())
- OS << "<mcsymbol> ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
OS << CFI.getOffset();
break;
case MCCFIInstruction::OpDefCfa:
OS << "def_cfa ";
- if (CFI.getLabel())
- OS << "<mcsymbol> ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
+ printCFIRegister(CFI.getRegister(), OS, TRI);
+ OS << ", " << CFI.getOffset();
+ break;
+ case MCCFIInstruction::OpRelOffset:
+ OS << "rel_offset ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
printCFIRegister(CFI.getRegister(), OS, TRI);
OS << ", " << CFI.getOffset();
break;
+ case MCCFIInstruction::OpAdjustCfaOffset:
+ OS << "adjust_cfa_offset ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
+ OS << CFI.getOffset();
+ break;
case MCCFIInstruction::OpRestore:
OS << "restore ";
- if (CFI.getLabel())
- OS << "<mcsymbol> ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
+ printCFIRegister(CFI.getRegister(), OS, TRI);
+ break;
+ case MCCFIInstruction::OpEscape: {
+ OS << "escape ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
+ if (!CFI.getValues().empty()) {
+ size_t e = CFI.getValues().size() - 1;
+ for (size_t i = 0; i < e; ++i)
+ OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", ";
+ OS << format("0x%02x", uint8_t(CFI.getValues()[e])) << ", ";
+ }
+ break;
+ }
+ case MCCFIInstruction::OpUndefined:
+ OS << "undefined ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
printCFIRegister(CFI.getRegister(), OS, TRI);
break;
+ case MCCFIInstruction::OpRegister:
+ OS << "register ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
+ printCFIRegister(CFI.getRegister(), OS, TRI);
+ OS << ", ";
+ printCFIRegister(CFI.getRegister2(), OS, TRI);
+ break;
+ case MCCFIInstruction::OpWindowSave:
+ OS << "window_save ";
+ if (MCSymbol *Label = CFI.getLabel())
+ MachineOperand::printSymbol(OS, *Label);
+ break;
default:
// TODO: Print the other CFI Operations.
OS << "<unserializable cfi operation>";
OS << ") ";
}
+void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
+ OS << "<mcsymbol " << Sym << ">";
+}
+
void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
const TargetIntrinsicInfo *IntrinsicInfo) const {
tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
getMetadata()->printAsOperand(OS, MST);
break;
case MachineOperand::MO_MCSymbol:
- OS << "<mcsymbol " << *getMCSymbol() << ">";
+ printSymbol(OS, *getMCSymbol());
break;
case MachineOperand::MO_CFIIndex:
OS << "<call frame instruction>";
ret void
}
- define void @trivial_fp_func_restore() {
- entry:
- call void @foo()
- ret void
- }
-
...
---
name: trivial_fp_func
# CHECK-LABEL: name: trivial_fp_func
body: |
bb.0.entry:
- liveins: %lr, %fp, %lr, %fp
-
- %sp = frame-setup STPXpre killed %fp, killed %lr, %sp, -2
- %fp = frame-setup ADDXri %sp, 0, 0
; CHECK: CFI_INSTRUCTION def_cfa %w29, 16
frame-setup CFI_INSTRUCTION def_cfa %w29, 16
- frame-setup CFI_INSTRUCTION offset %w30, -8
- frame-setup CFI_INSTRUCTION offset %w29, -16
- BL @foo, csr_aarch64_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp
- %sp, %fp, %lr = LDPXpost %sp, 2
- RET_ReallyLR
-...
----
-name: trivial_fp_func_restore
-# CHECK-LABEL: name: trivial_fp_func_restore
-body: |
- bb.0.entry:
- liveins: %lr, %fp
-
- %sp = frame-setup STPXpre killed %fp, killed %lr, %sp, -2
- %fp = frame-setup ADDXri %sp, 0, 0
- frame-setup CFI_INSTRUCTION def_cfa %w29, 16
- frame-setup CFI_INSTRUCTION offset %w30, -8
+ ; CHECK: CFI_INSTRUCTION def_cfa_register %w29
+ frame-setup CFI_INSTRUCTION def_cfa_register %w29
+ ; CHECK: CFI_INSTRUCTION def_cfa_offset -8
+ frame-setup CFI_INSTRUCTION def_cfa_offset -8
; CHECK: CFI_INSTRUCTION offset %w30, -8
- frame-setup CFI_INSTRUCTION offset %w29, -16
- ; CHECK: CFI_INSTRUCTION offset %w29, -16
- BL @foo, csr_aarch64_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp
- %sp, %fp, %lr = LDPXpost %sp, 2
+ frame-setup CFI_INSTRUCTION offset %w30, -8
+ ; CHECK: CFI_INSTRUCTION rel_offset %w30, -8
+ frame-setup CFI_INSTRUCTION rel_offset %w30, -8
+ ; CHECK: CFI_INSTRUCTION adjust_cfa_offset -8
+ frame-setup CFI_INSTRUCTION adjust_cfa_offset -8
CFI_INSTRUCTION restore %w30
; CHECK: CFI_INSTRUCTION restore %w30
- CFI_INSTRUCTION restore %w29
- ; CHECK: CFI_INSTRUCTION restore %w29
+ CFI_INSTRUCTION undefined %w30
+ ; CHECK: CFI_INSTRUCTION undefined %w30
+ CFI_INSTRUCTION same_value %w29
+ ; CHECK: CFI_INSTRUCTION same_value %w29
+ CFI_INSTRUCTION register %w20, %w30
+ ; CHECK: CFI_INSTRUCTION register %w20, %w30
+ CFI_INSTRUCTION remember_state
+ ; CHECK: CFI_INSTRUCTION remember_state
+ CFI_INSTRUCTION restore_state
+ ; CHECK: CFI_INSTRUCTION restore_state
+ CFI_INSTRUCTION escape 0x61, 0x62, 0x63
+ ; CHECK: CFI_INSTRUCTION escape 0x61, 0x62, 0x63
+ CFI_INSTRUCTION window_save
+ ; CHECK: CFI_INSTRUCTION window_save
RET_ReallyLR
-...
ADJCALLSTACKDOWN32 4, 0, 4, implicit-def dead %esp, implicit-def dead %eflags, implicit-def dead %ssp, implicit %esp, implicit %ssp, debug-location !33
DBG_VALUE %fixed-stack.1, 0, !14, !DIExpression(), debug-location !20
PUSH32r %ebx, implicit-def %esp, implicit %esp, debug-location !33
- ;CFI_INSTRUCTION <unserializable cfi operation>, debug-location !33
+ CFI_INSTRUCTION adjust_cfa_offset 4, debug-location !33
CALLpcrel32 @doSomething, csr_32, implicit %esp, implicit %ssp, implicit-def %esp, implicit-def %ssp, implicit-def %eax, debug-location !33
ADJCALLSTACKUP32 4, 0, implicit-def dead %esp, implicit-def dead %eflags, implicit-def dead %ssp, implicit %esp, implicit %ssp, debug-location !33
%edi = INC32r killed %edi, implicit-def dead %eflags, debug-location !30