diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Lanai/LanaiAluCode.h')
-rw-r--r-- | contrib/llvm/lib/Target/Lanai/LanaiAluCode.h | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/Lanai/LanaiAluCode.h b/contrib/llvm/lib/Target/Lanai/LanaiAluCode.h new file mode 100644 index 000000000000..b6ceedef6651 --- /dev/null +++ b/contrib/llvm/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 |