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