148 lines
3.5 KiB
C++
148 lines
3.5 KiB
C++
//===-- LanaiAluCode.h - ALU operator encoding ----------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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
|
|
const int Lanai_PRE_OP = 0x40;
|
|
const 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
|