aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Lanai/LanaiAluCode.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Lanai/LanaiAluCode.h')
-rw-r--r--lib/Target/Lanai/LanaiAluCode.h148
1 files changed, 148 insertions, 0 deletions
diff --git a/lib/Target/Lanai/LanaiAluCode.h b/lib/Target/Lanai/LanaiAluCode.h
new file mode 100644
index 000000000000..b6ceedef6651
--- /dev/null
+++ b/lib/Target/Lanai/LanaiAluCode.h
@@ -0,0 +1,148 @@
+//===-- LanaiAluCode.h - ALU operator encoding ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The encoding for ALU operators used in RM and RRM operands
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
+#define LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
+
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+namespace LPAC {
+enum AluCode {
+ ADD = 0x00,
+ ADDC = 0x01,
+ SUB = 0x02,
+ SUBB = 0x03,
+ AND = 0x04,
+ OR = 0x05,
+ XOR = 0x06,
+ SPECIAL = 0x07,
+
+ // Shift instructions are treated as SPECIAL when encoding the machine
+ // instruction, but kept distinct until lowering. The constant values are
+ // chosen to ease lowering.
+ SHL = 0x17,
+ SRL = 0x27,
+ SRA = 0x37,
+
+ // Indicates an unknown/unsupported operator
+ UNKNOWN = 0xFF,
+};
+
+// Bits indicating post- and pre-operators should be tested and set using Is*
+// and Make* utility functions
+constexpr int Lanai_PRE_OP = 0x40;
+constexpr int Lanai_POST_OP = 0x80;
+
+inline static unsigned encodeLanaiAluCode(unsigned AluOp) {
+ unsigned const OP_ENCODING_MASK = 0x07;
+ return AluOp & OP_ENCODING_MASK;
+}
+
+inline static unsigned getAluOp(unsigned AluOp) {
+ unsigned const ALU_MASK = 0x3F;
+ return AluOp & ALU_MASK;
+}
+
+inline static bool isPreOp(unsigned AluOp) { return AluOp & Lanai_PRE_OP; }
+
+inline static bool isPostOp(unsigned AluOp) { return AluOp & Lanai_POST_OP; }
+
+inline static unsigned makePreOp(unsigned AluOp) {
+ assert(!isPostOp(AluOp) && "Operator can't be a post- and pre-op");
+ return AluOp | Lanai_PRE_OP;
+}
+
+inline static unsigned makePostOp(unsigned AluOp) {
+ assert(!isPreOp(AluOp) && "Operator can't be a post- and pre-op");
+ return AluOp | Lanai_POST_OP;
+}
+
+inline static bool modifiesOp(unsigned AluOp) {
+ return isPreOp(AluOp) | isPostOp(AluOp);
+}
+
+inline static const char *lanaiAluCodeToString(unsigned AluOp) {
+ switch (getAluOp(AluOp)) {
+ case ADD:
+ return "add";
+ case ADDC:
+ return "addc";
+ case SUB:
+ return "sub";
+ case SUBB:
+ return "subb";
+ case AND:
+ return "and";
+ case OR:
+ return "or";
+ case XOR:
+ return "xor";
+ case SHL:
+ return "sh";
+ case SRL:
+ return "sh";
+ case SRA:
+ return "sha";
+ default:
+ llvm_unreachable("Invalid ALU code.");
+ }
+}
+
+inline static AluCode stringToLanaiAluCode(StringRef S) {
+ return StringSwitch<AluCode>(S)
+ .Case("add", ADD)
+ .Case("addc", ADDC)
+ .Case("sub", SUB)
+ .Case("subb", SUBB)
+ .Case("and", AND)
+ .Case("or", OR)
+ .Case("xor", XOR)
+ .Case("sh", SHL)
+ .Case("srl", SRL)
+ .Case("sha", SRA)
+ .Default(UNKNOWN);
+}
+
+inline static AluCode isdToLanaiAluCode(ISD::NodeType Node_type) {
+ switch (Node_type) {
+ case ISD::ADD:
+ return AluCode::ADD;
+ case ISD::ADDE:
+ return AluCode::ADDC;
+ case ISD::SUB:
+ return AluCode::SUB;
+ case ISD::SUBE:
+ return AluCode::SUBB;
+ case ISD::AND:
+ return AluCode::AND;
+ case ISD::OR:
+ return AluCode::OR;
+ case ISD::XOR:
+ return AluCode::XOR;
+ case ISD::SHL:
+ return AluCode::SHL;
+ case ISD::SRL:
+ return AluCode::SRL;
+ case ISD::SRA:
+ return AluCode::SRA;
+ default:
+ return AluCode::UNKNOWN;
+ }
+}
+} // namespace LPAC
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H