diff options
Diffstat (limited to 'backend/lib')
| -rw-r--r-- | backend/lib/TableGen/Parser.cpp | 69 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc | 30 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVMCPseudoLowering.rccdesc | 35 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp | 9 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp | 187 |
6 files changed, 145 insertions, 195 deletions
diff --git a/backend/lib/TableGen/Parser.cpp b/backend/lib/TableGen/Parser.cpp index c383aed..67c7a43 100644 --- a/backend/lib/TableGen/Parser.cpp +++ b/backend/lib/TableGen/Parser.cpp @@ -41,7 +41,7 @@ public: "register_classes", "register_masks", "mir_operand_flags", "named_operands", "immediate_predicates", "scheduling_classes", "encoding_categories", "assembly_formats", "calling_conventions", "instructions", "selection_rules", - "combiner_rules", "macro_fusion_rules"}, + "combiner_rules", "macro_fusion_rules", "mc_pseudo_expansions"}, "target description root")) { return std::nullopt; } @@ -84,6 +84,7 @@ public: const yaml::Node *SelectionRulesNode = optionalNode(*Root, "selection_rules"); const yaml::Node *CombinerRulesNode = optionalNode(*Root, "combiner_rules"); const yaml::Node *MacroFusionRulesNode = optionalNode(*Root, "macro_fusion_rules"); + const yaml::Node *MCPseudoExpansionsNode = optionalNode(*Root, "mc_pseudo_expansions"); if (UnitsNode == nullptr || RegistersNode == nullptr || BanksNode == nullptr || ClassesNode == nullptr || MasksNode == nullptr || NamedOperandsNode == nullptr || ImmediatePredicatesNode == nullptr || SchedulingClassesNode == nullptr || @@ -108,7 +109,9 @@ public: (CombinerRulesNode != nullptr && !parseCombinerRules(*CombinerRulesNode, Result.CombinerRules)) || (MacroFusionRulesNode != nullptr && - !parseMacroFusionRules(*MacroFusionRulesNode, Result.MacroFusionRules))) { + !parseMacroFusionRules(*MacroFusionRulesNode, Result.MacroFusionRules)) || + (MCPseudoExpansionsNode != nullptr && + !parseMCPseudoExpansions(*MCPseudoExpansionsNode, Result.MCPseudoExpansions))) { return std::nullopt; } return Result; @@ -2099,6 +2102,68 @@ private: return true; } + [[nodiscard]] bool parseMCPseudoOperands(const yaml::Node &Node, + std::vector<SourceMCPseudoOperand> &Result) { + if (!requireSequence(&Node, "MC pseudo expansion operands")) + return false; + for (const yaml::NodeID ElementID : Node.sequence()) { + const yaml::Node *Element = Input.node(ElementID); + if (!requireMapping(Element, "MC pseudo expansion operand") || + !checkKeys(*Element, {"operand", "register", "immediate"}, + "MC pseudo expansion operand")) { + return false; + } + SourceMCPseudoOperand Operand; + Operand.Range = Element->range(); + if (const yaml::Node *SourceNode = optionalNode(*Element, "operand")) { + const auto Source = unsignedInteger32(*SourceNode, "MC pseudo source operand"); + if (!Source) + return false; + Operand.SourceOperandIndex = *Source; + } + if (const yaml::Node *RegisterNode = optionalNode(*Element, "register")) { + const auto Register = scalar(*RegisterNode, "MC pseudo fixed register"); + if (!Register) + return false; + Operand.RegisterSymbol = *Register; + } + if (const yaml::Node *ImmediateNode = optionalNode(*Element, "immediate")) { + const auto Immediate = signedInteger(*ImmediateNode, "MC pseudo fixed immediate"); + if (!Immediate) + return false; + Operand.Immediate = *Immediate; + } + Result.push_back(std::move(Operand)); + } + return true; + } + + [[nodiscard]] bool parseMCPseudoExpansions(const yaml::Node &Node, + std::vector<SourceMCPseudoExpansion> &Result) { + if (!requireSequence(&Node, "mc_pseudo_expansions")) + return false; + for (const yaml::NodeID ElementID : Node.sequence()) { + const yaml::Node *Element = Input.node(ElementID); + if (!requireMapping(Element, "MC pseudo expansion") || + !checkKeys(*Element, {"pseudo", "opcode", "operands"}, "MC pseudo expansion")) { + return false; + } + const auto Pseudo = requiredScalar(*Element, "pseudo", "MC pseudo expansion"); + const auto Opcode = requiredScalar(*Element, "opcode", "MC pseudo expansion"); + const yaml::Node *OperandsNode = requiredNode(*Element, "operands", "MC pseudo expansion"); + if (!Pseudo || !Opcode || OperandsNode == nullptr) + return false; + SourceMCPseudoExpansion Expansion; + Expansion.PseudoOpcodeSymbol = *Pseudo; + Expansion.ResultOpcodeSymbol = *Opcode; + Expansion.Range = Element->range(); + if (!parseMCPseudoOperands(*OperandsNode, Expansion.Operands)) + return false; + Result.push_back(std::move(Expansion)); + } + return true; + } + [[nodiscard]] bool parseInstructions(const yaml::Node &Node, std::vector<SourceInstruction> &Result) { if (!requireSequence(&Node, "instructions")) diff --git a/backend/lib/Target/RISCV/CMakeLists.txt b/backend/lib/Target/RISCV/CMakeLists.txt index 00de7bd..dccced9 100644 --- a/backend/lib/Target/RISCV/CMakeLists.txt +++ b/backend/lib/Target/RISCV/CMakeLists.txt @@ -21,6 +21,7 @@ set( "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelFloating.rccdesc" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelCombiner.rccdesc" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVMacroFusion.rccdesc" + "${CMAKE_CURRENT_SOURCE_DIR}/RISCVMCPseudoLowering.rccdesc" ) set(RCCBackendRISCVTableGenArguments) foreach(RCCBackendRISCVDescriptionSource IN LISTS RCCBackendRISCVDescriptionSources) @@ -50,6 +51,10 @@ set( RCCBackendRISCVGeneratedMacroFusion "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV/RISCVGenMacroFusion.inc" ) +set( + RCCBackendRISCVGeneratedMCPseudoLowering + "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV/RISCVGenMCPseudoLowering.inc" +) add_custom_command( OUTPUT @@ -59,6 +64,7 @@ add_custom_command( "${RCCBackendRISCVGeneratedGlobalISel}" "${RCCBackendRISCVGeneratedGlobalISelCombiner}" "${RCCBackendRISCVGeneratedMacroFusion}" + "${RCCBackendRISCVGeneratedMCPseudoLowering}" COMMAND "$<TARGET_FILE:RCCBackendTableGenTool>" ${RCCBackendRISCVTableGenArguments} @@ -68,6 +74,7 @@ add_custom_command( --global-isel "${RCCBackendRISCVGeneratedGlobalISel}" --global-isel-combiner "${RCCBackendRISCVGeneratedGlobalISelCombiner}" --macro-fusion "${RCCBackendRISCVGeneratedMacroFusion}" + --mc-pseudo-lowering "${RCCBackendRISCVGeneratedMCPseudoLowering}" DEPENDS RCCBackendTableGenTool ${RCCBackendRISCVDescriptionSources} COMMENT "Generating RCC RV64GC target tables" VERBATIM @@ -82,6 +89,7 @@ add_custom_target( "${RCCBackendRISCVGeneratedGlobalISel}" "${RCCBackendRISCVGeneratedGlobalISelCombiner}" "${RCCBackendRISCVGeneratedMacroFusion}" + "${RCCBackendRISCVGeneratedMCPseudoLowering}" ) set_source_files_properties( @@ -91,6 +99,7 @@ set_source_files_properties( "${RCCBackendRISCVGeneratedGlobalISel}" "${RCCBackendRISCVGeneratedGlobalISelCombiner}" "${RCCBackendRISCVGeneratedMacroFusion}" + "${RCCBackendRISCVGeneratedMCPseudoLowering}" PROPERTIES GENERATED TRUE HEADER_FILE_ONLY TRUE ) @@ -127,6 +136,7 @@ add_library( "${RCCBackendRISCVGeneratedGlobalISel}" "${RCCBackendRISCVGeneratedGlobalISelCombiner}" "${RCCBackendRISCVGeneratedMacroFusion}" + "${RCCBackendRISCVGeneratedMCPseudoLowering}" ) add_library(RCCBackend::RISCV ALIAS RCCBackendRISCV) add_dependencies(RCCBackendRISCV RCCBackendRISCVGeneratedTablesTarget) diff --git a/backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc b/backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc index 14bcf26..3e458df 100644 --- a/backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc +++ b/backend/lib/Target/RISCV/RISCVInstrInfoPseudo.rccdesc @@ -227,9 +227,9 @@ instructions: - { kinds: [register], role: def, register_class: GPR, register_bank: GPR } num_explicit_defs: 1 implicit_uses: [{ register: FFLAGS }] - flags: [pseudo, produces_code, allowed_pre_legalizer, has_side_effects] - owner: post_ra_expansion - deadline: post_ra_finalized + flags: [pseudo, produces_code, allowed_pre_legalizer, has_side_effects, terminal_emission] + owner: asm_printer + deadline: emission - id: 1246 @@ -239,9 +239,9 @@ instructions: - { kinds: [register], role: use, register_class: GPR, register_bank: GPR } num_explicit_defs: 0 implicit_defs: [{ register: FFLAGS }] - flags: [pseudo, produces_code, allowed_pre_legalizer, has_side_effects] - owner: post_ra_expansion - deadline: post_ra_finalized + flags: [pseudo, produces_code, allowed_pre_legalizer, has_side_effects, terminal_emission] + owner: asm_printer + deadline: emission - id: 1217 symbol: PseudoLOAD_STACK_ARG @@ -342,10 +342,10 @@ instructions: operands: [] num_explicit_defs: 0 allow_extra_implicit_operands: true - flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, return, barrier] + flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, return, barrier, terminal_emission] size: 4 - owner: post_ra_expansion - deadline: post_ra_finalized + owner: asm_printer + deadline: emission - id: 1225 @@ -404,10 +404,10 @@ instructions: operands: - { kinds: [basic_block], name: TARGET } num_explicit_defs: 0 - flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, branch, barrier] + flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, branch, barrier, terminal_emission] size: 4 - owner: post_ra_expansion - deadline: post_ra_finalized + owner: asm_printer + deadline: emission - id: 1267 symbol: PseudoLLA @@ -441,7 +441,7 @@ instructions: - { kinds: [register], role: use, register_class: GPRJALRNonX7, register_bank: GPR, name: RS1 } - { kinds: [immediate], immediate_predicate: SIMM12, name: IMM } num_explicit_defs: 0 - flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, branch, indirect_branch, barrier] + flags: [pseudo, produces_code, allowed_pre_legalizer, terminator, branch, indirect_branch, barrier, terminal_emission] size: 4 - owner: post_ra_expansion - deadline: post_ra_finalized + owner: asm_printer + deadline: emission diff --git a/backend/lib/Target/RISCV/RISCVMCPseudoLowering.rccdesc b/backend/lib/Target/RISCV/RISCVMCPseudoLowering.rccdesc new file mode 100644 index 0000000..a505281 --- /dev/null +++ b/backend/lib/Target/RISCV/RISCVMCPseudoLowering.rccdesc @@ -0,0 +1,35 @@ +mc_pseudo_expansions: + - + pseudo: PseudoBR + opcode: JAL + operands: + - { register: X0 } + - { operand: 0 } + - + pseudo: PseudoBRIND + opcode: JALR + operands: + - { register: X0 } + - { operand: 0 } + - { operand: 1 } + - + pseudo: PseudoRET + opcode: JALR + operands: + - { register: X0 } + - { register: X1 } + - { immediate: 0 } + - + pseudo: ReadFFLAGS + opcode: CSRRS + operands: + - { operand: 0 } + - { immediate: 1 } + - { register: X0 } + - + pseudo: WriteFFLAGS + opcode: CSRRW + operands: + - { register: X0 } + - { immediate: 1 } + - { operand: 0 } diff --git a/backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp b/backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp index 61cb587..85c06ad 100644 --- a/backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp +++ b/backend/lib/Target/RISCV/RISCVMCTargetLowering.cpp @@ -240,6 +240,10 @@ constexpr std::uint32_t KnownTargetFlags = CallTargetFlag | PCRelativeHighTarget "RISC-V MC lowering encountered a non-encoding operand"); } +#define GET_MC_PSEUDO_LOWERING +#include "RISCVGenMCPseudoLowering.inc" +#undef GET_MC_PSEUDO_LOWERING + [[nodiscard]] const AssemblyFormatInfo *assemblyFormat(AssemblyFormatID ID) noexcept { const auto Formats = assemblyFormats(); const auto Position = std::ranges::find(Formats, ID, &AssemblyFormatInfo::ID); @@ -866,6 +870,11 @@ Expected<mc::MCInst> RISCVMCTargetLowering::lowerInstruction(const MachineInstr Expected<void> RISCVMCTargetLowering::emitTerminalInstruction(const MachineInstr &Instruction, MachineMCContext &Context, mc::MCStreamer &Streamer) const { + auto Pseudo = lowerGeneratedMCPseudo(Instruction, Context); + if (!Pseudo) + return std::unexpected(Pseudo.error()); + if (*Pseudo) + return Streamer.emitInstruction(**Pseudo); if (Instruction.opcode() != opcode(GenericOpcode::INLINEASM) && Instruction.opcode() != opcode(GenericOpcode::INLINEASM_BR)) { return TargetMCInstLowering::emitTerminalInstruction(Instruction, Context, Streamer); diff --git a/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp b/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp index 257fa3a..19e52d9 100644 --- a/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp +++ b/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp @@ -243,7 +243,15 @@ copyRegisters(const MachineInstr &Instruction) { auto Def = Pending->addDef(Destination); if (!Def) return std::unexpected(Def.error()); - auto Use = Pending->addUse(Source); + RegisterOperandFlags SourceFlags; + const RegisterOperandFlags OriginalSourceFlags = Instruction.operandAt(1)->registerFlags(); + if (OriginalSourceFlags.has(RegisterOperandFlag::Kill)) + SourceFlags.set(RegisterOperandFlag::Kill); + if (*DestinationBank == GPR && *SourceBank == GPR && + OriginalSourceFlags.has(RegisterOperandFlag::Renamable)) { + SourceFlags.set(RegisterOperandFlag::Renamable); + } + auto Use = Pending->addUse(Source, SourceFlags); if (!Use) return std::unexpected(Use.error()); if (DuplicateSource) { @@ -440,53 +448,6 @@ copyRegisters(const MachineInstr &Instruction) { return {}; } -[[nodiscard]] Expected<bool> expandFFLAGSAccess(MachineInstr &Instruction, - MachineFunction &Function, - const TargetDescription &Target, bool IsRead) { - const MachineOperand *ValueOperand = Instruction.operandAt(0); - const Register *Value = ValueOperand == nullptr ? nullptr : ValueOperand->getIf<Register>(); - if (Value == nullptr || !Value->isPhysical()) { - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V FFLAGS pseudo retains a nonphysical value register"); - } - auto Zero = physicalRegister(PhysicalRegisterID::X0); - if (!Zero) - return std::unexpected(Zero.error()); - - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Pending = Builder.buildInstr( - instructionOpcode(IsRead ? InstructionOpcode::CSRRS : InstructionOpcode::CSRRW)); - if (!Pending) - return std::unexpected(Pending.error()); - Expected<void> Added = IsRead ? Pending->addOperand(ValueOperand->cloneDetached()) - : Pending->addDef(Register::fromPhysical(*Zero)); - if (!Added) - return std::unexpected(Added.error()); - Added = Pending->addImmediate(1); - if (!Added) - return std::unexpected(Added.error()); - Added = IsRead ? Pending->addUse(Register::fromPhysical(*Zero)) - : Pending->addOperand(ValueOperand->cloneDetached()); - if (!Added) - return std::unexpected(Added.error()); - auto Implicit = copyExtraImplicitOperands(Instruction, 1, *Pending, std::nullopt, std::nullopt); - if (!Implicit) - return std::unexpected(Implicit.error()); - auto Replacement = Pending->build(); - if (!Replacement) - return std::unexpected(Replacement.error()); - auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true); - if (!Decoration) - return std::unexpected(Decoration.error()); - auto Removed = removeOldInstruction(Instruction); - if (!Removed) - return std::unexpected(Removed.error()); - return true; -} - [[nodiscard]] Expected<bool> expandCall(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target, bool IsTail) { MachineBasicBlock *Block = Instruction.parent(); @@ -585,126 +546,6 @@ copyRegisters(const MachineInstr &Instruction) { return true; } -[[nodiscard]] Expected<bool> expandReturn(MachineInstr &Instruction, MachineFunction &Function, - const TargetDescription &Target) { - auto Zero = physicalRegister(PhysicalRegisterID::X0); - auto Link = physicalRegister(PhysicalRegisterID::X1); - if (!Zero || !Link) - return makeUnexpected(ErrorCode::InternalError, "RISC-V return registers are unavailable"); - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JALR_RET)); - if (!Pending) - return std::unexpected(Pending.error()); - auto Def = Pending->addDef(Register::fromPhysical(*Zero)); - if (!Def) - return std::unexpected(Def.error()); - auto Use = Pending->addUse(Register::fromPhysical(*Link)); - if (!Use) - return std::unexpected(Use.error()); - auto Immediate = Pending->addImmediate(0); - if (!Immediate) - return std::unexpected(Immediate.error()); - auto Implicit = copyExtraImplicitOperands(Instruction, 0, *Pending, std::nullopt, *Link); - if (!Implicit) - return std::unexpected(Implicit.error()); - auto Replacement = Pending->build(); - if (!Replacement) - return std::unexpected(Replacement.error()); - auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true); - if (!Decoration) - return std::unexpected(Decoration.error()); - auto Removed = removeOldInstruction(Instruction); - if (!Removed) - return std::unexpected(Removed.error()); - return true; -} - -[[nodiscard]] Expected<bool> expandBranch(MachineInstr &Instruction, MachineFunction &Function, - const TargetDescription &Target) { - const MachineOperand *TargetOperand = Instruction.operandAt(0); - const BasicBlockOperand *TargetBlock = - TargetOperand == nullptr ? nullptr : TargetOperand->getIf<BasicBlockOperand>(); - if (TargetBlock == nullptr || TargetBlock->Block == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V PseudoBR has no basic-block target"); - } - - auto Zero = physicalRegister(PhysicalRegisterID::X0); - if (!Zero) - return std::unexpected(Zero.error()); - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JAL)); - if (!Pending) - return std::unexpected(Pending.error()); - auto Def = Pending->addDef(Register::fromPhysical(*Zero)); - if (!Def) - return std::unexpected(Def.error()); - auto Destination = Pending->addBasicBlock(*TargetBlock->Block); - if (!Destination) - return std::unexpected(Destination.error()); - auto Replacement = Pending->build(); - if (!Replacement) - return std::unexpected(Replacement.error()); - auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true); - if (!Decoration) - return std::unexpected(Decoration.error()); - auto Removed = removeOldInstruction(Instruction); - if (!Removed) - return std::unexpected(Removed.error()); - return true; -} - -[[nodiscard]] Expected<bool> expandIndirectBranch(MachineInstr &Instruction, - MachineFunction &Function, - const TargetDescription &Target) { - const MachineOperand *Address = Instruction.operandAt(0); - const MachineOperand *Offset = Instruction.operandAt(1); - if (Address == nullptr || Address->getIf<Register>() == nullptr || Offset == nullptr || - Offset->getIf<std::int64_t>() == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V PseudoBRIND has malformed operands"); - } - - auto Zero = physicalRegister(PhysicalRegisterID::X0); - if (!Zero) - return std::unexpected(Zero.error()); - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JALR)); - if (!Pending) - return std::unexpected(Pending.error()); - auto Added = Pending->addDef(Register::fromPhysical(*Zero)); - if (!Added) - return std::unexpected(Added.error()); - Added = Pending->addOperand(Address->cloneDetached()); - if (!Added) - return std::unexpected(Added.error()); - Added = Pending->addOperand(Offset->cloneDetached()); - if (!Added) - return std::unexpected(Added.error()); - auto Implicit = copyExtraImplicitOperands(Instruction, 2, *Pending, std::nullopt, std::nullopt); - if (!Implicit) - return std::unexpected(Implicit.error()); - auto Replacement = Pending->build(); - if (!Replacement) - return std::unexpected(Replacement.error()); - auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true); - if (!Decoration) - return std::unexpected(Decoration.error()); - auto Removed = removeOldInstruction(Instruction); - if (!Removed) - return std::unexpected(Removed.error()); - return true; -} - class RISCVPseudoExpansionInfo final : public TargetPseudoExpansionInfo { public: [[nodiscard]] Expected<bool> preparePostRAPseudo(MachineInstr &Instruction, @@ -735,16 +576,6 @@ public: return expandCall(Instruction, Function, Target, false); if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoTAIL)) return expandCall(Instruction, Function, Target, true); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoRET)) - return expandReturn(Instruction, Function, Target); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoBR)) - return expandBranch(Instruction, Function, Target); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoBRIND)) - return expandIndirectBranch(Instruction, Function, Target); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::ReadFFLAGS)) - return expandFFLAGSAccess(Instruction, Function, Target, true); - if (Instruction.opcode() == instructionOpcode(InstructionOpcode::WriteFFLAGS)) - return expandFFLAGSAccess(Instruction, Function, Target, false); return false; } }; |
