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_H
17 #define MAPLEBE_INCLUDE_CG_X64_X64_ISA_H
18
19 #include "operand.h"
20 #include "isa.h"
21
22 namespace maplebe {
23 /*
24 * X64 Architecture Reference Manual
25 */
26 constexpr int kX64StackPtrAlignment = 16;
27
28 constexpr int32 kX64OffsetAlign = 8;
29 constexpr uint32 kX64IntregBytelen = 8; /* 64-bit */
30 constexpr uint32 kX64FpregBytelen = 8; /* only lower 64 bits are used */
31 constexpr int kX64SizeOfFplr = 16;
32
33 class Insn;
34
35 namespace x64 {
36 /* machine instruction description */
37 #define DEFINE_MOP(op, ...) op,
38 enum X64MOP_t : maple::uint32 {
39 #include "abstract_mmir.def"
40 #include "x64_md.def"
41 kMopLast
42 };
43 #undef DEFINE_MOP
44
45 /* Registers in x64 state */
46 enum X64reg : uint32 {
47 kRinvalid = kInvalidRegNO,
48 /* integer registers */
49 #define INT_REG(ID, PREF8, PREF8_16, PREF16, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, \
50 isExtraSpill) \
51 R##ID,
52 #define INT_REG_ALIAS(ALIAS, ID)
53 #include "x64_int_regs.def"
54 #undef INT_REG
55 #undef INT_REG_ALIAS
56 /* fp-simd registers */
57 #define FP_SIMD_REG(ID, P8, P16, P32, P64, P128, canBeAssigned, isCalleeSave, isParam, isSpill, isExtraSpill) V##ID,
58 #include "x64_fp_simd_regs.def"
59 #undef FP_SIMD_REG
60 kMaxRegNum,
61 kRFLAG,
62 kAllRegNum,
63 /* integer registers alias */
64 #define INT_REG(ID, PREF8, PREF8_16, PREF16, PREF32, PREF64, canBeAssigned, isCalleeSave, isParam, isSpill, \
65 isExtraSpill)
66 #define INT_REG_ALIAS(ALIAS, ID) R##ALIAS = R##ID,
67 #include "x64_int_regs.def"
68 #undef INT_REG
69 #undef INT_REG_ALIAS
70 };
71
IsGPRegister(X64reg r)72 static inline bool IsGPRegister(X64reg r)
73 {
74 return R0 <= r && r <= RLAST_GP_REG;
75 }
76
IsFPSIMDRegister(X64reg r)77 static inline bool IsFPSIMDRegister(X64reg r)
78 {
79 return V0 <= r && r <= V15;
80 }
81
IsFPRegister(X64reg r)82 static inline bool IsFPRegister(X64reg r)
83 {
84 return V0 <= r && r <= V7;
85 }
86
IsSIMDRegister(X64reg r)87 static inline bool IsSIMDRegister(X64reg r)
88 {
89 return V8 <= r && r <= V15;
90 }
91
IsPhysicalRegister(regno_t r)92 static inline bool IsPhysicalRegister(regno_t r)
93 {
94 return r < kMaxRegNum;
95 }
96
GetRegType(X64reg r)97 static inline RegType GetRegType(X64reg r)
98 {
99 if (IsGPRegister(r)) {
100 return kRegTyInt;
101 }
102 if (IsFPSIMDRegister(r)) {
103 return kRegTyFloat;
104 }
105 DEBUG_ASSERT(false, "No suitable register type to return?");
106 return kRegTyUndef;
107 }
108 /*
109 * Precondition: The given insn is a jump instruction.
110 * Get the jump target label operand index from the given instruction.
111 * Note: MOP_jmp_m, MOP_jmp_r is a jump instruction, but the target is unknown at compile time.
112 */
113 uint32 GetJumpTargetIdx(const Insn &insn);
114
115 MOperator FlipConditionOp(MOperator flippedOp);
116 } /* namespace x64 */
117
118 /*
119 * We save callee-saved registers from lower stack area to upper stack area.
120 * If possible, we store a pair of registers (int/int and fp/fp) in the stack.
121 * The Stack Pointer has to be aligned at 16-byte boundary.
122 * On X64, kX64IntregBytelen == 8 (see the above)
123 */
GetNextOffsetCalleeSaved(int & offset)124 inline void GetNextOffsetCalleeSaved(int &offset)
125 {
126 offset += (kX64IntregBytelen << 1);
127 }
128 } /* namespace maplebe */
129
130 #endif /* MAPLEBE_INCLUDE_CG_X64_X64_ISA_H */
131