1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef MAPLEBE_INCLUDE_CG_X64_X64_ISA_TBL_H
17 #define MAPLEBE_INCLUDE_CG_X64_X64_ISA_TBL_H
18
19 #include "x64_isa.h"
20 #include "operand.h"
21
22 namespace maplebe {
23
24 namespace x64 {
25 /* register, imm , memory, cond */
26 #define DEF_X64_CMP_MAPPING_INT(SIZE) \
27 static const X64MOP_t cmpIselMap##SIZE[Operand::OperandType::kOpdPhi][Operand::OperandType::kOpdPhi] = { \
28 {MOP_cmp##SIZE##_r_r, MOP_begin, MOP_cmp##SIZE##_r_m, MOP_begin}, \
29 {MOP_cmp##SIZE##_i_r, MOP_begin, MOP_cmp##SIZE##_i_m, MOP_begin}, \
30 {MOP_cmp##SIZE##_m_r, MOP_begin, MOP_begin, MOP_begin}, \
31 {MOP_begin, MOP_begin, MOP_begin, MOP_begin}, \
32 }
33 DEF_X64_CMP_MAPPING_INT(b);
34 DEF_X64_CMP_MAPPING_INT(w);
35 DEF_X64_CMP_MAPPING_INT(l);
36 DEF_X64_CMP_MAPPING_INT(q);
37
GetCmpMop(Operand::OperandType dTy,Operand::OperandType sTy,PrimType primType)38 static inline X64MOP_t GetCmpMop(Operand::OperandType dTy, Operand::OperandType sTy, PrimType primType)
39 {
40 X64MOP_t cmpOp = MOP_begin;
41 switch (GetPrimTypeBitSize(primType)) {
42 case k8BitSize:
43 cmpOp = cmpIselMapb[sTy][dTy];
44 break;
45 case k16BitSize:
46 cmpOp = cmpIselMapw[sTy][dTy];
47 break;
48 case k32BitSize:
49 cmpOp = cmpIselMapl[sTy][dTy];
50 break;
51 case k64BitSize:
52 cmpOp = cmpIselMapq[sTy][dTy];
53 break;
54 default:
55 cmpOp = MOP_begin;
56 break;
57 }
58 return cmpOp;
59 }
60
61 /* {OPCODE, {register, imm , memory, cond}} */
62 #define DEF_X64_SET_MAPPING_INT(OPCODE, TYPE) \
63 { \
64 OPCODE, \
65 { \
66 x64::MOP_##TYPE##_r, x64::MOP_begin, x64::MOP_##TYPE##_m, x64::MOP_begin \
67 } \
68 }
69
70 using SetIselMappingType = std::unordered_map<maple::Opcode, std::array<X64MOP_t, Operand::OperandType::kOpdPhi>>;
71 static const SetIselMappingType setUnsignedIselMapping = {
72 DEF_X64_SET_MAPPING_INT(OP_le, setbe), DEF_X64_SET_MAPPING_INT(OP_ge, setae), DEF_X64_SET_MAPPING_INT(OP_gt, seta),
73 DEF_X64_SET_MAPPING_INT(OP_lt, setb), DEF_X64_SET_MAPPING_INT(OP_ne, setne), DEF_X64_SET_MAPPING_INT(OP_eq, sete),
74 };
75 static const SetIselMappingType setSignedIselMapping = {
76 DEF_X64_SET_MAPPING_INT(OP_le, setle), DEF_X64_SET_MAPPING_INT(OP_ge, setge), DEF_X64_SET_MAPPING_INT(OP_gt, setg),
77 DEF_X64_SET_MAPPING_INT(OP_lt, setl), DEF_X64_SET_MAPPING_INT(OP_ne, setne), DEF_X64_SET_MAPPING_INT(OP_eq, sete),
78 };
79 static const SetIselMappingType setFloatIselMapping = {
80 DEF_X64_SET_MAPPING_INT(OP_le, setae), DEF_X64_SET_MAPPING_INT(OP_ge, setae), DEF_X64_SET_MAPPING_INT(OP_gt, seta),
81 DEF_X64_SET_MAPPING_INT(OP_lt, seta), DEF_X64_SET_MAPPING_INT(OP_ne, setne), DEF_X64_SET_MAPPING_INT(OP_eq, sete),
82 };
83 #undef DEF_X64_SET_MAPPING_INT
84
GetSetCCMop(maple::Opcode opcode,Operand::OperandType dTy,bool isSigned,bool isFloat)85 static inline X64MOP_t GetSetCCMop(maple::Opcode opcode, Operand::OperandType dTy, bool isSigned, bool isFloat)
86 {
87 DEBUG_ASSERT(dTy < Operand::OperandType::kOpdPhi, "illegal operand type");
88 const SetIselMappingType &setIselMapping =
89 isFloat ? setFloatIselMapping : (isSigned ? setSignedIselMapping : setUnsignedIselMapping);
90 auto iter = setIselMapping.find(opcode);
91 if (iter == setIselMapping.end()) {
92 return x64::MOP_begin;
93 }
94 return iter->second[dTy];
95 }
96
97 #define DEF_X64_CMOV_MAPPING_INT(OPCODE, TYPE) \
98 { \
99 OPCODE, \
100 { \
101 x64::MOP_begin, x64::MOP_##TYPE##w_r_r, x64::MOP_##TYPE##l_r_r, x64::MOP_##TYPE##q_r_r \
102 } \
103 }
104 using CMovIselMappingType = std::unordered_map<maple::Opcode, std::array<X64MOP_t, kBitIndexEnd>>;
105 static const CMovIselMappingType cmovUnsignedIselMapping = {
106 DEF_X64_CMOV_MAPPING_INT(OP_le, cmovbe), DEF_X64_CMOV_MAPPING_INT(OP_ge, cmovae),
107 DEF_X64_CMOV_MAPPING_INT(OP_gt, cmova), DEF_X64_CMOV_MAPPING_INT(OP_lt, cmovb),
108 DEF_X64_CMOV_MAPPING_INT(OP_ne, cmovne), DEF_X64_CMOV_MAPPING_INT(OP_eq, cmove),
109 };
110 static const CMovIselMappingType cmovSignedIselMapping = {
111 DEF_X64_CMOV_MAPPING_INT(OP_le, cmovle), DEF_X64_CMOV_MAPPING_INT(OP_ge, cmovge),
112 DEF_X64_CMOV_MAPPING_INT(OP_gt, cmovg), DEF_X64_CMOV_MAPPING_INT(OP_lt, cmovl),
113 DEF_X64_CMOV_MAPPING_INT(OP_ne, cmovne), DEF_X64_CMOV_MAPPING_INT(OP_eq, cmove),
114 };
115 #undef DEF_X64_CMOV_MAPPING_INT
116
GetCMovCCMop(maple::Opcode opcode,int32 bitSize,bool isSigned)117 static inline X64MOP_t GetCMovCCMop(maple::Opcode opcode, int32 bitSize, bool isSigned)
118 {
119 const auto &cmovIselMapping = isSigned ? cmovSignedIselMapping : cmovUnsignedIselMapping;
120 auto iter = cmovIselMapping.find(opcode);
121 if (iter == cmovIselMapping.end()) {
122 return x64::MOP_begin;
123 }
124 return iter->second[GetBitIndex(bitSize)];
125 }
126 } // namespace x64
127 } /* namespace maplebe */
128
129 #endif /* MAPLEBE_INCLUDE_CG_X64_X64_ISA_TBL_H */
130