//===-- 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