diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrFormats.td | 4 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 58 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.h | 11 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstructionSelector.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstructionSelector.h | 5 |
6 files changed, 85 insertions, 3 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 6bc301abef9..d57e1db1d33 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -689,6 +689,10 @@ def addsub_shifted_imm64 : addsub_shifted_imm<i64>; def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; +def gi_addsub_shifted_imm32 : + GIComplexOperandMatcher<s32, (ops i32imm, i32imm), "selectArithImmed">, + GIComplexPatternEquiv<addsub_shifted_imm32>; + class neg_addsub_shifted_imm<ValueType Ty> : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { let PrintMethod = "printAddSubImm"; diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index 1656b5c6efc..e4f3fa86c13 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -37,13 +37,20 @@ using namespace llvm; #error "You shouldn't build this" #endif +#define GET_GLOBALISEL_IMPL #include "AArch64GenGlobalISel.inc" +#undef GET_GLOBALISEL_IMPL AArch64InstructionSelector::AArch64InstructionSelector( const AArch64TargetMachine &TM, const AArch64Subtarget &STI, const AArch64RegisterBankInfo &RBI) - : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), - TRI(*STI.getRegisterInfo()), RBI(RBI) {} + : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), + TRI(*STI.getRegisterInfo()), RBI(RBI) +#define GET_GLOBALISEL_TEMPORARIES_INIT +#include "AArch64GenGlobalISel.inc" +#undef GET_GLOBALISEL_TEMPORARIES_INIT +{ +} // FIXME: This should be target-independent, inferred from the types declared // for each class in the bank. @@ -1213,3 +1220,50 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { return false; } + +/// SelectArithImmed - Select an immediate value that can be represented as +/// a 12-bit value shifted left by either 0 or 12. If so, return true with +/// Val set to the 12-bit value and Shift set to the shifter operand. +bool AArch64InstructionSelector::selectArithImmed( + MachineOperand &Root, MachineOperand &Result1, + MachineOperand &Result2) const { + MachineInstr &MI = *Root.getParent(); + MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MBB.getParent(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + + // This function is called from the addsub_shifted_imm ComplexPattern, + // which lists [imm] as the list of opcode it's interested in, however + // we still need to check whether the operand is actually an immediate + // here because the ComplexPattern opcode list is only used in + // root-level opcode matching. + uint64_t Immed; + if (Root.isImm()) + Immed = Root.getImm(); + else if (Root.isCImm()) + Immed = Root.getCImm()->getZExtValue(); + else if (Root.isReg()) { + MachineInstr *Def = MRI.getVRegDef(Root.getReg()); + if (Def->getOpcode() != TargetOpcode::G_CONSTANT) + return false; + Immed = Def->getOperand(1).getImm(); + } else + return false; + + unsigned ShiftAmt; + + if (Immed >> 12 == 0) { + ShiftAmt = 0; + } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) { + ShiftAmt = 12; + Immed = Immed >> 12; + } else + return false; + + unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt); + Result1.ChangeToImmediate(Immed); + Result1.clearParent(); + Result2.ChangeToImmediate(ShVal); + Result2.clearParent(); + return true; +} diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.h b/llvm/lib/Target/AArch64/AArch64InstructionSelector.h index 3f38c9fcd1a..6c9339e05d6 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.h +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.h @@ -15,6 +15,7 @@ #define LLVM_LIB_TARGET_AARCH64_AARCH64INSTRUCTIONSELECTOR_H #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +#include "llvm/CodeGen/MachineOperand.h" namespace llvm { @@ -23,6 +24,7 @@ class AArch64RegisterBankInfo; class AArch64RegisterInfo; class AArch64Subtarget; class AArch64TargetMachine; +class MachineOperand; class MachineFunction; class MachineRegisterInfo; @@ -45,11 +47,20 @@ private: /// the patterns that don't require complex C++. bool selectImpl(MachineInstr &I) const; + bool selectArithImmed(MachineOperand &Root, MachineOperand &Result1, + MachineOperand &Result2) const; + const AArch64TargetMachine &TM; const AArch64Subtarget &STI; const AArch64InstrInfo &TII; const AArch64RegisterInfo &TRI; const AArch64RegisterBankInfo &RBI; + +// We declare the temporaries used by selectImpl() in the class to minimize the +// cost of constructing placeholder values. +#define GET_GLOBALISEL_TEMPORARIES_DECL +#include "AArch64GenGlobalISel.inc" +#undef GET_GLOBALISEL_TEMPORARIES_DECL }; } // end namespace llvm diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 78a9144bd32..e0aecff2633 100644 --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -661,6 +661,7 @@ static bool IsAnAddressOperand(const MachineOperand &MO) { return false; case MachineOperand::MO_IntrinsicID: case MachineOperand::MO_Predicate: + case MachineOperand::MO_Placeholder: llvm_unreachable("should not exist post-isel"); } llvm_unreachable("unhandled machine operand type"); diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp index 0927c96abaa..2dbe4b4834e 100644 --- a/llvm/lib/Target/X86/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp @@ -35,12 +35,19 @@ using namespace llvm; #error "You shouldn't build this" #endif +#define GET_GLOBALISEL_IMPL #include "X86GenGlobalISel.inc" +#undef GET_GLOBALISEL_IMPL X86InstructionSelector::X86InstructionSelector(const X86Subtarget &STI, const X86RegisterBankInfo &RBI) : InstructionSelector(), STI(STI), TII(*STI.getInstrInfo()), - TRI(*STI.getRegisterInfo()), RBI(RBI) {} + TRI(*STI.getRegisterInfo()), RBI(RBI) +#define GET_GLOBALISEL_TEMPORARIES_INIT +#include "X86GenGlobalISel.inc" +#undef GET_GLOBALISEL_TEMPORARIES_INIT +{ +} // FIXME: This should be target-independent, inferred from the types declared // for each class in the bank. diff --git a/llvm/lib/Target/X86/X86InstructionSelector.h b/llvm/lib/Target/X86/X86InstructionSelector.h index 19f34fc6168..205c8626656 100644 --- a/llvm/lib/Target/X86/X86InstructionSelector.h +++ b/llvm/lib/Target/X86/X86InstructionSelector.h @@ -14,6 +14,7 @@ #define LLVM_LIB_TARGET_X86_X86INSTRUCTIONSELECTOR_H #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +#include "llvm/CodeGen/MachineOperand.h" namespace llvm { @@ -49,6 +50,10 @@ private: const X86InstrInfo &TII; const X86RegisterInfo &TRI; const X86RegisterBankInfo &RBI; + +#define GET_GLOBALISEL_TEMPORARIES_DECL +#include "X86GenGlobalISel.inc" +#undef GET_GLOBALISEL_TEMPORARIES_DECL }; } // end namespace llvm |