/// Generic store.
HANDLE_TARGET_OPCODE(G_STORE)
+/// Generic atomic cmpxchg.
+HANDLE_TARGET_OPCODE(G_ATOMIC_CMPXCHG)
+
+/// Generic atomicrmw.
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_XCHG)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_ADD)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_SUB)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_AND)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_NAND)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_OR)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_XOR)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_MAX)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_MIN)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMAX)
+HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMIN)
+
/// Generic conditional branch instruction.
HANDLE_TARGET_OPCODE(G_BRCOND)
let mayStore = 1;
}
+// Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
+// operands.
+def G_ATOMIC_CMPXCHG : Instruction {
+ let OutOperandList = (outs type0:$oldval);
+ let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
+ let hasSideEffects = 0;
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+
+// Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
+// operands.
+class G_ATOMICRMW_OP : Instruction {
+ let OutOperandList = (outs type0:$oldval);
+ let InOperandList = (ins ptype1:$addr, type0:$val);
+ let hasSideEffects = 0;
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+
+def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_ADD : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_SUB : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_AND : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_NAND : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_OR : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_XOR : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_MAX : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_MIN : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP {
+ // FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
+ // block which overrides the value inherited from G_ATOMICRMW_OP. Work
+ // around this for now. See http://reviews.llvm.org/D40096
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+
//------------------------------------------------------------------------------
// Variadic ops
//------------------------------------------------------------------------------
//===----------------------------------------------------------------------===//
#include "AArch64LegalizerInfo.h"
+#include "AArch64Subtarget.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
return result;
}
-AArch64LegalizerInfo::AArch64LegalizerInfo() {
+AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
using namespace TargetOpcode;
const LLT p0 = LLT::pointer(0, 64);
const LLT s1 = LLT::scalar(1);
for (auto Ty : {s8, s16, s32, s64, p0})
setAction({G_VAARG, Ty}, Custom);
+ if (ST.hasLSE()) {
+ for (auto Ty : {s8, s16, s32, s64})
+ setAction({G_ATOMIC_CMPXCHG, Ty}, Legal);
+ setAction({G_ATOMIC_CMPXCHG, 1, p0}, Legal);
+
+ for (auto Op :
+ {G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_AND,
+ G_ATOMICRMW_OR, G_ATOMICRMW_XOR, G_ATOMICRMW_MIN, G_ATOMICRMW_MAX,
+ G_ATOMICRMW_UMIN, G_ATOMICRMW_UMAX}) {
+ for (auto Ty : {s8, s16, s32, s64}) {
+ setAction({Op, Ty}, Legal);
+ }
+ setAction({Op, 1, p0}, Legal);
+ }
+ }
+
computeTables();
}