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 | |
19 | namespace llvm { |
20 | namespace LPAC { |
21 | enum 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 |
44 | const int Lanai_PRE_OP = 0x40; |
45 | const int Lanai_POST_OP = 0x80; |
46 | |
47 | inline static unsigned encodeLanaiAluCode(unsigned AluOp) { |
48 | unsigned const OP_ENCODING_MASK = 0x07; |
49 | return AluOp & OP_ENCODING_MASK; |
50 | } |
51 | |
52 | inline static unsigned getAluOp(unsigned AluOp) { |
53 | unsigned const ALU_MASK = 0x3F; |
54 | return AluOp & ALU_MASK; |
55 | } |
56 | |
57 | inline static bool isPreOp(unsigned AluOp) { return AluOp & Lanai_PRE_OP; } |
58 | |
59 | inline static bool isPostOp(unsigned AluOp) { return AluOp & Lanai_POST_OP; } |
60 | |
61 | inline 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 | |
66 | inline 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 | |
71 | inline static bool modifiesOp(unsigned AluOp) { |
72 | return isPreOp(AluOp) || isPostOp(AluOp); |
73 | } |
74 | |
75 | inline 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 | |
102 | inline 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 | |