1 //===-- LanaiAluCode.h - ALU operator encoding ----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // The encoding for ALU operators used in RM and RRM operands
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
15 #define LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
16
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/CodeGen/ISDOpcodes.h"
19 #include "llvm/Support/ErrorHandling.h"
20
21 namespace llvm {
22 namespace LPAC {
23 enum AluCode {
24 ADD = 0x00,
25 ADDC = 0x01,
26 SUB = 0x02,
27 SUBB = 0x03,
28 AND = 0x04,
29 OR = 0x05,
30 XOR = 0x06,
31 SPECIAL = 0x07,
32
33 // Shift instructions are treated as SPECIAL when encoding the machine
34 // instruction, but kept distinct until lowering. The constant values are
35 // chosen to ease lowering.
36 SHL = 0x17,
37 SRL = 0x27,
38 SRA = 0x37,
39
40 // Indicates an unknown/unsupported operator
41 UNKNOWN = 0xFF,
42 };
43
44 // Bits indicating post- and pre-operators should be tested and set using Is*
45 // and Make* utility functions
46 constexpr int Lanai_PRE_OP = 0x40;
47 constexpr int Lanai_POST_OP = 0x80;
48
encodeLanaiAluCode(unsigned AluOp)49 inline static unsigned encodeLanaiAluCode(unsigned AluOp) {
50 unsigned const OP_ENCODING_MASK = 0x07;
51 return AluOp & OP_ENCODING_MASK;
52 }
53
getAluOp(unsigned AluOp)54 inline static unsigned getAluOp(unsigned AluOp) {
55 unsigned const ALU_MASK = 0x3F;
56 return AluOp & ALU_MASK;
57 }
58
isPreOp(unsigned AluOp)59 inline static bool isPreOp(unsigned AluOp) { return AluOp & Lanai_PRE_OP; }
60
isPostOp(unsigned AluOp)61 inline static bool isPostOp(unsigned AluOp) { return AluOp & Lanai_POST_OP; }
62
makePreOp(unsigned AluOp)63 inline static unsigned makePreOp(unsigned AluOp) {
64 assert(!isPostOp(AluOp) && "Operator can't be a post- and pre-op");
65 return AluOp | Lanai_PRE_OP;
66 }
67
makePostOp(unsigned AluOp)68 inline static unsigned makePostOp(unsigned AluOp) {
69 assert(!isPreOp(AluOp) && "Operator can't be a post- and pre-op");
70 return AluOp | Lanai_POST_OP;
71 }
72
modifiesOp(unsigned AluOp)73 inline static bool modifiesOp(unsigned AluOp) {
74 return isPreOp(AluOp) | isPostOp(AluOp);
75 }
76
lanaiAluCodeToString(unsigned AluOp)77 inline static const char *lanaiAluCodeToString(unsigned AluOp) {
78 switch (getAluOp(AluOp)) {
79 case ADD:
80 return "add";
81 case ADDC:
82 return "addc";
83 case SUB:
84 return "sub";
85 case SUBB:
86 return "subb";
87 case AND:
88 return "and";
89 case OR:
90 return "or";
91 case XOR:
92 return "xor";
93 case SHL:
94 return "sh";
95 case SRL:
96 return "sh";
97 case SRA:
98 return "sha";
99 default:
100 llvm_unreachable("Invalid ALU code.");
101 }
102 }
103
stringToLanaiAluCode(StringRef S)104 inline static AluCode stringToLanaiAluCode(StringRef S) {
105 return StringSwitch<AluCode>(S)
106 .Case("add", ADD)
107 .Case("addc", ADDC)
108 .Case("sub", SUB)
109 .Case("subb", SUBB)
110 .Case("and", AND)
111 .Case("or", OR)
112 .Case("xor", XOR)
113 .Case("sh", SHL)
114 .Case("srl", SRL)
115 .Case("sha", SRA)
116 .Default(UNKNOWN);
117 }
118
isdToLanaiAluCode(ISD::NodeType Node_type)119 inline static AluCode isdToLanaiAluCode(ISD::NodeType Node_type) {
120 switch (Node_type) {
121 case ISD::ADD:
122 return AluCode::ADD;
123 case ISD::ADDE:
124 return AluCode::ADDC;
125 case ISD::SUB:
126 return AluCode::SUB;
127 case ISD::SUBE:
128 return AluCode::SUBB;
129 case ISD::AND:
130 return AluCode::AND;
131 case ISD::OR:
132 return AluCode::OR;
133 case ISD::XOR:
134 return AluCode::XOR;
135 case ISD::SHL:
136 return AluCode::SHL;
137 case ISD::SRL:
138 return AluCode::SRL;
139 case ISD::SRA:
140 return AluCode::SRA;
141 default:
142 return AluCode::UNKNOWN;
143 }
144 }
145 } // namespace LPAC
146 } // namespace llvm
147
148 #endif // LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
149