xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiAluCode.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- LanaiAluCode.h - ALU operator encoding ----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // The encoding for ALU operators used in RM and RRM operands
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
170b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace llvm {
200b57cec5SDimitry Andric namespace LPAC {
210b57cec5SDimitry Andric enum AluCode {
220b57cec5SDimitry Andric   ADD = 0x00,
230b57cec5SDimitry Andric   ADDC = 0x01,
240b57cec5SDimitry Andric   SUB = 0x02,
250b57cec5SDimitry Andric   SUBB = 0x03,
260b57cec5SDimitry Andric   AND = 0x04,
270b57cec5SDimitry Andric   OR = 0x05,
280b57cec5SDimitry Andric   XOR = 0x06,
290b57cec5SDimitry Andric   SPECIAL = 0x07,
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric   // Shift instructions are treated as SPECIAL when encoding the machine
320b57cec5SDimitry Andric   // instruction, but kept distinct until lowering. The constant values are
330b57cec5SDimitry Andric   // chosen to ease lowering.
340b57cec5SDimitry Andric   SHL = 0x17,
350b57cec5SDimitry Andric   SRL = 0x27,
360b57cec5SDimitry Andric   SRA = 0x37,
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   // Indicates an unknown/unsupported operator
390b57cec5SDimitry Andric   UNKNOWN = 0xFF,
400b57cec5SDimitry Andric };
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric // Bits indicating post- and pre-operators should be tested and set using Is*
430b57cec5SDimitry Andric // and Make* utility functions
440b57cec5SDimitry Andric const int Lanai_PRE_OP = 0x40;
450b57cec5SDimitry Andric const int Lanai_POST_OP = 0x80;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric inline static unsigned encodeLanaiAluCode(unsigned AluOp) {
480b57cec5SDimitry Andric   unsigned const OP_ENCODING_MASK = 0x07;
490b57cec5SDimitry Andric   return AluOp & OP_ENCODING_MASK;
500b57cec5SDimitry Andric }
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric inline static unsigned getAluOp(unsigned AluOp) {
530b57cec5SDimitry Andric   unsigned const ALU_MASK = 0x3F;
540b57cec5SDimitry Andric   return AluOp & ALU_MASK;
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric inline static bool isPreOp(unsigned AluOp) { return AluOp & Lanai_PRE_OP; }
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric inline static bool isPostOp(unsigned AluOp) { return AluOp & Lanai_POST_OP; }
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric inline static unsigned makePreOp(unsigned AluOp) {
620b57cec5SDimitry Andric   assert(!isPostOp(AluOp) && "Operator can't be a post- and pre-op");
630b57cec5SDimitry Andric   return AluOp | Lanai_PRE_OP;
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric inline static unsigned makePostOp(unsigned AluOp) {
670b57cec5SDimitry Andric   assert(!isPreOp(AluOp) && "Operator can't be a post- and pre-op");
680b57cec5SDimitry Andric   return AluOp | Lanai_POST_OP;
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric inline static bool modifiesOp(unsigned AluOp) {
72*349cc55cSDimitry Andric   return isPreOp(AluOp) || isPostOp(AluOp);
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric inline static const char *lanaiAluCodeToString(unsigned AluOp) {
760b57cec5SDimitry Andric   switch (getAluOp(AluOp)) {
770b57cec5SDimitry Andric   case ADD:
780b57cec5SDimitry Andric     return "add";
790b57cec5SDimitry Andric   case ADDC:
800b57cec5SDimitry Andric     return "addc";
810b57cec5SDimitry Andric   case SUB:
820b57cec5SDimitry Andric     return "sub";
830b57cec5SDimitry Andric   case SUBB:
840b57cec5SDimitry Andric     return "subb";
850b57cec5SDimitry Andric   case AND:
860b57cec5SDimitry Andric     return "and";
870b57cec5SDimitry Andric   case OR:
880b57cec5SDimitry Andric     return "or";
890b57cec5SDimitry Andric   case XOR:
900b57cec5SDimitry Andric     return "xor";
910b57cec5SDimitry Andric   case SHL:
920b57cec5SDimitry Andric     return "sh";
930b57cec5SDimitry Andric   case SRL:
940b57cec5SDimitry Andric     return "sh";
950b57cec5SDimitry Andric   case SRA:
960b57cec5SDimitry Andric     return "sha";
970b57cec5SDimitry Andric   default:
980b57cec5SDimitry Andric     llvm_unreachable("Invalid ALU code.");
990b57cec5SDimitry Andric   }
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric inline static AluCode stringToLanaiAluCode(StringRef S) {
1030b57cec5SDimitry Andric   return StringSwitch<AluCode>(S)
1040b57cec5SDimitry Andric       .Case("add", ADD)
1050b57cec5SDimitry Andric       .Case("addc", ADDC)
1060b57cec5SDimitry Andric       .Case("sub", SUB)
1070b57cec5SDimitry Andric       .Case("subb", SUBB)
1080b57cec5SDimitry Andric       .Case("and", AND)
1090b57cec5SDimitry Andric       .Case("or", OR)
1100b57cec5SDimitry Andric       .Case("xor", XOR)
1110b57cec5SDimitry Andric       .Case("sh", SHL)
1120b57cec5SDimitry Andric       .Case("srl", SRL)
1130b57cec5SDimitry Andric       .Case("sha", SRA)
1140b57cec5SDimitry Andric       .Default(UNKNOWN);
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric } // namespace LPAC
1170b57cec5SDimitry Andric } // namespace llvm
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_LANAI_LANAIALUCODE_H
120