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/Support/ErrorHandling.h"
18
19namespace llvm {
20namespace LPAC {
21enum AluCode {
22 ADD = 0x00,
23 ADDC = 0x01,
24 SUB = 0x02,
25 SUBB = 0x03,
26 AND = 0x04,
27 OR = 0x05,
28 XOR = 0x06,
29 SPECIAL = 0x07,
30
31 // Shift instructions are treated as SPECIAL when encoding the machine
32 // instruction, but kept distinct until lowering. The constant values are
33 // chosen to ease lowering.
34 SHL = 0x17,
35 SRL = 0x27,
36 SRA = 0x37,
37
38 // Indicates an unknown/unsupported operator
39 UNKNOWN = 0xFF,
40};
41
42// Bits indicating post- and pre-operators should be tested and set using Is*
43// and Make* utility functions
44const int Lanai_PRE_OP = 0x40;
45const int Lanai_POST_OP = 0x80;
46
47inline static unsigned encodeLanaiAluCode(unsigned AluOp) {
48 unsigned const OP_ENCODING_MASK = 0x07;
49 return AluOp & OP_ENCODING_MASK;
50}
51
52inline static unsigned getAluOp(unsigned AluOp) {
53 unsigned const ALU_MASK = 0x3F;
54 return AluOp & ALU_MASK;
55}
56
57inline static bool isPreOp(unsigned AluOp) { return AluOp & Lanai_PRE_OP; }
58
59inline static bool isPostOp(unsigned AluOp) { return AluOp & Lanai_POST_OP; }
60
61inline static unsigned makePreOp(unsigned AluOp) {
62 assert(!isPostOp(AluOp) && "Operator can't be a post- and pre-op");
63 return AluOp | Lanai_PRE_OP;
64}
65
66inline static unsigned makePostOp(unsigned AluOp) {
67 assert(!isPreOp(AluOp) && "Operator can't be a post- and pre-op");
68 return AluOp | Lanai_POST_OP;
69}
70
71inline static bool modifiesOp(unsigned AluOp) {
72 return isPreOp(AluOp) || isPostOp(AluOp);
73}
74
75inline static const char *lanaiAluCodeToString(unsigned AluOp) {
76 switch (getAluOp(AluOp)) {
77 case ADD:
78 return "add";
79 case ADDC:
80 return "addc";
81 case SUB:
82 return "sub";
83 case SUBB:
84 return "subb";
85 case AND:
86 return "and";
87 case OR:
88 return "or";
89 case XOR:
90 return "xor";
91 case SHL:
92 return "sh";
93 case SRL:
94 return "sh";
95 case SRA:
96 return "sha";
97 default:
98 llvm_unreachable("Invalid ALU code.");
99 }
100}
101
102inline static AluCode stringToLanaiAluCode(StringRef S) {
103 return StringSwitch<AluCode>(S)
104 .Case(S: "add", Value: ADD)
105 .Case(S: "addc", Value: ADDC)
106 .Case(S: "sub", Value: SUB)
107 .Case(S: "subb", Value: SUBB)
108 .Case(S: "and", Value: AND)
109 .Case(S: "or", Value: OR)
110 .Case(S: "xor", Value: XOR)
111 .Case(S: "sh", Value: SHL)
112 .Case(S: "srl", Value: SRL)
113 .Case(S: "sha", Value: SRA)
114 .Default(Value: UNKNOWN);
115}
116} // namespace LPAC
117} // namespace llvm
118
119#endif // LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
120