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