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