mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
MIR Serialization: Serialize MachineFrameInfo's callee saved information.
This commit serializes the callee saved information from the class 'MachineFrameInfo'. This commit extends the YAML mappings for the fixed and the ordinary stack objects and adds an optional 'callee-saved-register' attribute. This attribute is used to serialize the callee save information. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243173 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5136ca2c6d
commit
3a8b87d9ce
@ -159,6 +159,7 @@ struct MachineStackObject {
|
|||||||
int64_t Offset = 0;
|
int64_t Offset = 0;
|
||||||
uint64_t Size = 0;
|
uint64_t Size = 0;
|
||||||
unsigned Alignment = 0;
|
unsigned Alignment = 0;
|
||||||
|
StringValue CalleeSavedRegister;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
|
template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
|
||||||
@ -181,6 +182,8 @@ template <> struct MappingTraits<MachineStackObject> {
|
|||||||
if (Object.Type != MachineStackObject::VariableSized)
|
if (Object.Type != MachineStackObject::VariableSized)
|
||||||
YamlIO.mapRequired("size", Object.Size);
|
YamlIO.mapRequired("size", Object.Size);
|
||||||
YamlIO.mapOptional("alignment", Object.Alignment);
|
YamlIO.mapOptional("alignment", Object.Alignment);
|
||||||
|
YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
|
||||||
|
StringValue()); // Don't print it out when it's empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
static const bool flow = true;
|
static const bool flow = true;
|
||||||
@ -197,6 +200,7 @@ struct FixedMachineStackObject {
|
|||||||
unsigned Alignment = 0;
|
unsigned Alignment = 0;
|
||||||
bool IsImmutable = false;
|
bool IsImmutable = false;
|
||||||
bool IsAliased = false;
|
bool IsAliased = false;
|
||||||
|
StringValue CalleeSavedRegister;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@ -221,6 +225,8 @@ template <> struct MappingTraits<FixedMachineStackObject> {
|
|||||||
YamlIO.mapOptional("isImmutable", Object.IsImmutable);
|
YamlIO.mapOptional("isImmutable", Object.IsImmutable);
|
||||||
YamlIO.mapOptional("isAliased", Object.IsAliased);
|
YamlIO.mapOptional("isAliased", Object.IsAliased);
|
||||||
}
|
}
|
||||||
|
YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
|
||||||
|
StringValue()); // Don't print it out when it's empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
static const bool flow = true;
|
static const bool flow = true;
|
||||||
@ -296,7 +302,6 @@ struct MachineFrameInfo {
|
|||||||
bool HasCalls = false;
|
bool HasCalls = false;
|
||||||
// TODO: Serialize StackProtectorIdx and FunctionContextIdx
|
// TODO: Serialize StackProtectorIdx and FunctionContextIdx
|
||||||
unsigned MaxCallFrameSize = 0;
|
unsigned MaxCallFrameSize = 0;
|
||||||
// TODO: Serialize callee saved info.
|
|
||||||
// TODO: Serialize local frame objects.
|
// TODO: Serialize local frame objects.
|
||||||
bool HasOpaqueSPAdjustment = false;
|
bool HasOpaqueSPAdjustment = false;
|
||||||
bool HasVAStart = false;
|
bool HasVAStart = false;
|
||||||
|
@ -107,10 +107,15 @@ public:
|
|||||||
const yaml::MachineFunction &YamlMF,
|
const yaml::MachineFunction &YamlMF,
|
||||||
PerFunctionMIParsingState &PFS);
|
PerFunctionMIParsingState &PFS);
|
||||||
|
|
||||||
bool initializeFrameInfo(const Function &F, MachineFrameInfo &MFI,
|
bool initializeFrameInfo(MachineFunction &MF, MachineFrameInfo &MFI,
|
||||||
const yaml::MachineFunction &YamlMF,
|
const yaml::MachineFunction &YamlMF,
|
||||||
DenseMap<unsigned, int> &StackObjectSlots,
|
PerFunctionMIParsingState &PFS);
|
||||||
DenseMap<unsigned, int> &FixedStackObjectSlots);
|
|
||||||
|
bool parseCalleeSavedRegister(MachineFunction &MF,
|
||||||
|
PerFunctionMIParsingState &PFS,
|
||||||
|
std::vector<CalleeSavedInfo> &CSIInfo,
|
||||||
|
const yaml::StringValue &RegisterSource,
|
||||||
|
int FrameIdx);
|
||||||
|
|
||||||
bool initializeConstantPool(MachineConstantPool &ConstantPool,
|
bool initializeConstantPool(MachineConstantPool &ConstantPool,
|
||||||
const yaml::MachineFunction &YamlMF,
|
const yaml::MachineFunction &YamlMF,
|
||||||
@ -273,8 +278,7 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
|
|||||||
PerFunctionMIParsingState PFS;
|
PerFunctionMIParsingState PFS;
|
||||||
if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF, PFS))
|
if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF, PFS))
|
||||||
return true;
|
return true;
|
||||||
if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF,
|
if (initializeFrameInfo(MF, *MF.getFrameInfo(), YamlMF, PFS))
|
||||||
PFS.StackObjectSlots, PFS.FixedStackObjectSlots))
|
|
||||||
return true;
|
return true;
|
||||||
if (!YamlMF.Constants.empty()) {
|
if (!YamlMF.Constants.empty()) {
|
||||||
auto *ConstantPool = MF.getConstantPool();
|
auto *ConstantPool = MF.getConstantPool();
|
||||||
@ -401,11 +405,11 @@ bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MIRParserImpl::initializeFrameInfo(
|
bool MIRParserImpl::initializeFrameInfo(MachineFunction &MF,
|
||||||
const Function &F, MachineFrameInfo &MFI,
|
MachineFrameInfo &MFI,
|
||||||
const yaml::MachineFunction &YamlMF,
|
const yaml::MachineFunction &YamlMF,
|
||||||
DenseMap<unsigned, int> &StackObjectSlots,
|
PerFunctionMIParsingState &PFS) {
|
||||||
DenseMap<unsigned, int> &FixedStackObjectSlots) {
|
const Function &F = *MF.getFunction();
|
||||||
const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
|
const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
|
||||||
MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
|
MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
|
||||||
MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
|
MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
|
||||||
@ -422,6 +426,7 @@ bool MIRParserImpl::initializeFrameInfo(
|
|||||||
MFI.setHasVAStart(YamlMFI.HasVAStart);
|
MFI.setHasVAStart(YamlMFI.HasVAStart);
|
||||||
MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
|
MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
|
||||||
|
|
||||||
|
std::vector<CalleeSavedInfo> CSIInfo;
|
||||||
// Initialize the fixed frame objects.
|
// Initialize the fixed frame objects.
|
||||||
for (const auto &Object : YamlMF.FixedStackObjects) {
|
for (const auto &Object : YamlMF.FixedStackObjects) {
|
||||||
int ObjectIdx;
|
int ObjectIdx;
|
||||||
@ -432,7 +437,10 @@ bool MIRParserImpl::initializeFrameInfo(
|
|||||||
ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
|
ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
|
||||||
MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
|
MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
|
||||||
// TODO: Report an error when objects are redefined.
|
// TODO: Report an error when objects are redefined.
|
||||||
FixedStackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
|
PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
|
||||||
|
if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
|
||||||
|
ObjectIdx))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the ordinary frame objects.
|
// Initialize the ordinary frame objects.
|
||||||
@ -457,8 +465,29 @@ bool MIRParserImpl::initializeFrameInfo(
|
|||||||
Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
|
Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
|
||||||
MFI.setObjectOffset(ObjectIdx, Object.Offset);
|
MFI.setObjectOffset(ObjectIdx, Object.Offset);
|
||||||
// TODO: Report an error when objects are redefined.
|
// TODO: Report an error when objects are redefined.
|
||||||
StackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
|
PFS.StackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx));
|
||||||
|
if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
|
||||||
|
ObjectIdx))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
MFI.setCalleeSavedInfo(CSIInfo);
|
||||||
|
if (!CSIInfo.empty())
|
||||||
|
MFI.setCalleeSavedInfoValid(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MIRParserImpl::parseCalleeSavedRegister(
|
||||||
|
MachineFunction &MF, PerFunctionMIParsingState &PFS,
|
||||||
|
std::vector<CalleeSavedInfo> &CSIInfo,
|
||||||
|
const yaml::StringValue &RegisterSource, int FrameIdx) {
|
||||||
|
if (RegisterSource.Value.empty())
|
||||||
|
return false;
|
||||||
|
unsigned Reg = 0;
|
||||||
|
SMDiagnostic Error;
|
||||||
|
if (parseNamedRegisterReference(Reg, SM, MF, RegisterSource.Value, PFS,
|
||||||
|
IRSlots, Error))
|
||||||
|
return error(Error, RegisterSource.SourceRange);
|
||||||
|
CSIInfo.push_back(CalleeSavedInfo(Reg, FrameIdx));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,8 @@ public:
|
|||||||
void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
|
void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
|
||||||
const MachineBasicBlock &MBB);
|
const MachineBasicBlock &MBB);
|
||||||
void convertStackObjects(yaml::MachineFunction &MF,
|
void convertStackObjects(yaml::MachineFunction &MF,
|
||||||
const MachineFrameInfo &MFI);
|
const MachineFrameInfo &MFI,
|
||||||
|
const TargetRegisterInfo *TRI);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initRegisterMaskIds(const MachineFunction &MF);
|
void initRegisterMaskIds(const MachineFunction &MF);
|
||||||
@ -156,7 +157,8 @@ void MIRPrinter::print(const MachineFunction &MF) {
|
|||||||
YamlMF.HasInlineAsm = MF.hasInlineAsm();
|
YamlMF.HasInlineAsm = MF.hasInlineAsm();
|
||||||
convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
|
convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
|
||||||
convert(YamlMF.FrameInfo, *MF.getFrameInfo());
|
convert(YamlMF.FrameInfo, *MF.getFrameInfo());
|
||||||
convertStackObjects(YamlMF, *MF.getFrameInfo());
|
convertStackObjects(YamlMF, *MF.getFrameInfo(),
|
||||||
|
MF.getSubtarget().getRegisterInfo());
|
||||||
if (const auto *ConstantPool = MF.getConstantPool())
|
if (const auto *ConstantPool = MF.getConstantPool())
|
||||||
convert(YamlMF, *ConstantPool);
|
convert(YamlMF, *ConstantPool);
|
||||||
|
|
||||||
@ -219,7 +221,8 @@ void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
|
void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
|
||||||
const MachineFrameInfo &MFI) {
|
const MachineFrameInfo &MFI,
|
||||||
|
const TargetRegisterInfo *TRI) {
|
||||||
// Process fixed stack objects.
|
// Process fixed stack objects.
|
||||||
unsigned ID = 0;
|
unsigned ID = 0;
|
||||||
for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
|
for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
|
||||||
@ -265,6 +268,19 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
|
|||||||
StackObjectOperandMapping.insert(std::make_pair(
|
StackObjectOperandMapping.insert(std::make_pair(
|
||||||
I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
|
I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
|
||||||
|
yaml::StringValue Reg;
|
||||||
|
printReg(CSInfo.getReg(), Reg, TRI);
|
||||||
|
auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
|
||||||
|
assert(StackObjectInfo != StackObjectOperandMapping.end() &&
|
||||||
|
"Invalid stack object index");
|
||||||
|
const FrameIndexOperand &StackObject = StackObjectInfo->second;
|
||||||
|
if (StackObject.IsFixed)
|
||||||
|
MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
|
||||||
|
else
|
||||||
|
MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIRPrinter::convert(yaml::MachineFunction &MF,
|
void MIRPrinter::convert(yaml::MachineFunction &MF,
|
||||||
|
98
test/CodeGen/MIR/X86/callee-saved-info.mir
Normal file
98
test/CodeGen/MIR/X86/callee-saved-info.mir
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# RUN: llc -march=x86-64 -start-after prologepilog -stop-after prologepilog -o /dev/null %s | FileCheck %s
|
||||||
|
# This test ensures that the MIR parser parses callee saved information in the
|
||||||
|
# stack objects correctly.
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @compute(i32 %a) {
|
||||||
|
body:
|
||||||
|
ret i32 %a
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @func(i32 %a) {
|
||||||
|
entry:
|
||||||
|
%b = alloca i32
|
||||||
|
store i32 %a, i32* %b
|
||||||
|
br label %check
|
||||||
|
|
||||||
|
check:
|
||||||
|
%comp = icmp sle i32 %a, 10
|
||||||
|
br i1 %comp, label %loop, label %exit
|
||||||
|
|
||||||
|
loop:
|
||||||
|
%c = load i32, i32* %b
|
||||||
|
%d = call i32 @compute(i32 %c)
|
||||||
|
%e = sub i32 %d, 1
|
||||||
|
store i32 %e, i32* %b
|
||||||
|
br label %check
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: compute
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: body
|
||||||
|
liveins: [ '%edi' ]
|
||||||
|
instructions:
|
||||||
|
- '%eax = COPY killed %edi'
|
||||||
|
- 'RETQ killed %eax'
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: func
|
||||||
|
tracksRegLiveness: true
|
||||||
|
frameInfo:
|
||||||
|
stackSize: 24
|
||||||
|
maxAlignment: 4
|
||||||
|
adjustsStack: true
|
||||||
|
hasCalls: true
|
||||||
|
# CHECK: fixedStack:
|
||||||
|
# CHECK-NEXT: , callee-saved-register: '%rbx' }
|
||||||
|
fixedStack:
|
||||||
|
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '%rbx' }
|
||||||
|
# CHECK: stack:
|
||||||
|
# CHECK-NEXT: - { id: 0
|
||||||
|
# CHECK-NEXT: , callee-saved-register: '%edi' }
|
||||||
|
stack:
|
||||||
|
- { id: 0, name: b, offset: -20, size: 4, alignment: 4 }
|
||||||
|
- { id: 1, offset: -24, size: 4, alignment: 4, callee-saved-register: '%edi' }
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1.check' ]
|
||||||
|
liveins: [ '%edi', '%rbx' ]
|
||||||
|
instructions:
|
||||||
|
- 'frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp'
|
||||||
|
- '%rsp = frame-setup SUB64ri8 %rsp, 16, implicit-def dead %eflags'
|
||||||
|
- '%ebx = COPY %edi'
|
||||||
|
- 'MOV32mr %rsp, 1, _, 12, _, %ebx'
|
||||||
|
- id: 1
|
||||||
|
name: check
|
||||||
|
successors: [ '%bb.2.loop', '%bb.3.exit' ]
|
||||||
|
liveins: [ '%ebx' ]
|
||||||
|
instructions:
|
||||||
|
- 'CMP32ri8 %ebx, 10, implicit-def %eflags'
|
||||||
|
- 'JG_1 %bb.3.exit, implicit killed %eflags'
|
||||||
|
- 'JMP_1 %bb.2.loop'
|
||||||
|
- id: 2
|
||||||
|
name: loop
|
||||||
|
successors: [ '%bb.1.check' ]
|
||||||
|
liveins: [ '%ebx' ]
|
||||||
|
instructions:
|
||||||
|
- '%edi = MOV32rm %rsp, 1, _, 12, _'
|
||||||
|
- 'CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax'
|
||||||
|
- '%eax = DEC32r killed %eax, implicit-def dead %eflags'
|
||||||
|
- 'MOV32mr %rsp, 1, _, 12, _, killed %eax'
|
||||||
|
- 'JMP_1 %bb.1.check'
|
||||||
|
- id: 3
|
||||||
|
name: exit
|
||||||
|
instructions:
|
||||||
|
- '%eax = MOV32r0 implicit-def dead %eflags'
|
||||||
|
- '%rsp = ADD64ri8 %rsp, 16, implicit-def dead %eflags'
|
||||||
|
- '%rbx = POP64r implicit-def %rsp, implicit %rsp'
|
||||||
|
- 'RETQ %eax'
|
||||||
|
...
|
@ -0,0 +1,91 @@
|
|||||||
|
# RUN: not llc -march=x86-64 -start-after prologepilog -stop-after prologepilog -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
|
||||||
|
define i32 @compute(i32 %a) {
|
||||||
|
body:
|
||||||
|
ret i32 %a
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @func(i32 %a) {
|
||||||
|
entry:
|
||||||
|
%b = alloca i32
|
||||||
|
store i32 %a, i32* %b
|
||||||
|
br label %check
|
||||||
|
|
||||||
|
check:
|
||||||
|
%comp = icmp sle i32 %a, 10
|
||||||
|
br i1 %comp, label %loop, label %exit
|
||||||
|
|
||||||
|
loop:
|
||||||
|
%c = load i32, i32* %b
|
||||||
|
%d = call i32 @compute(i32 %c)
|
||||||
|
%e = sub i32 %d, 1
|
||||||
|
store i32 %e, i32* %b
|
||||||
|
br label %check
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: compute
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: body
|
||||||
|
liveins: [ '%edi' ]
|
||||||
|
instructions:
|
||||||
|
- '%eax = COPY killed %edi'
|
||||||
|
- 'RETQ killed %eax'
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: func
|
||||||
|
tracksRegLiveness: true
|
||||||
|
frameInfo:
|
||||||
|
stackSize: 24
|
||||||
|
maxAlignment: 4
|
||||||
|
adjustsStack: true
|
||||||
|
hasCalls: true
|
||||||
|
fixedStack:
|
||||||
|
# CHECK: [[@LINE+1]]:93: expected a named register
|
||||||
|
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '%0' }
|
||||||
|
stack:
|
||||||
|
- { id: 0, name: b, offset: -20, size: 4, alignment: 4 }
|
||||||
|
body:
|
||||||
|
- id: 0
|
||||||
|
name: entry
|
||||||
|
successors: [ '%bb.1.check' ]
|
||||||
|
liveins: [ '%edi', '%rbx' ]
|
||||||
|
instructions:
|
||||||
|
- 'frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp'
|
||||||
|
- '%rsp = frame-setup SUB64ri8 %rsp, 16, implicit-def dead %eflags'
|
||||||
|
- '%ebx = COPY %edi'
|
||||||
|
- 'MOV32mr %rsp, 1, _, 12, _, %ebx'
|
||||||
|
- id: 1
|
||||||
|
name: check
|
||||||
|
successors: [ '%bb.2.loop', '%bb.3.exit' ]
|
||||||
|
liveins: [ '%ebx' ]
|
||||||
|
instructions:
|
||||||
|
- 'CMP32ri8 %ebx, 10, implicit-def %eflags'
|
||||||
|
- 'JG_1 %bb.3.exit, implicit killed %eflags'
|
||||||
|
- 'JMP_1 %bb.2.loop'
|
||||||
|
- id: 2
|
||||||
|
name: loop
|
||||||
|
successors: [ '%bb.1.check' ]
|
||||||
|
liveins: [ '%ebx' ]
|
||||||
|
instructions:
|
||||||
|
- '%edi = MOV32rm %rsp, 1, _, 12, _'
|
||||||
|
- 'CALL64pcrel32 @compute, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax'
|
||||||
|
- '%eax = DEC32r killed %eax, implicit-def dead %eflags'
|
||||||
|
- 'MOV32mr %rsp, 1, _, 12, _, killed %eax'
|
||||||
|
- 'JMP_1 %bb.1.check'
|
||||||
|
- id: 3
|
||||||
|
name: exit
|
||||||
|
instructions:
|
||||||
|
- '%eax = MOV32r0 implicit-def dead %eflags'
|
||||||
|
- '%rsp = ADD64ri8 %rsp, 16, implicit-def dead %eflags'
|
||||||
|
- '%rbx = POP64r implicit-def %rsp, implicit %rsp'
|
||||||
|
- 'RETQ %eax'
|
||||||
|
...
|
Loading…
x
Reference in New Issue
Block a user