• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 COMPILER_OPTIMIZER_CODEGEN_ENCODE_H
17 #define COMPILER_OPTIMIZER_CODEGEN_ENCODE_H
18 
19 /*
20     Hi-level interface for encoding
21     Wrapper for specialize concrete used encoding
22 
23     Responsible for
24         Primitive (not-branch) instruction encoding
25         Memory-instructions encoding
26         Immediate and Memory operands
27 */
28 
29 #include <variant>
30 
31 #include "operands.h"
32 #include "registers_description.h"
33 #include "utils/cframe_layout.h"
34 #include "target_info.h"
35 
36 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
37 #define ENCODE_MATH_UNARY_OP_LIST(DEF) \
38     DEF(Mov, UNARY_OPERATION)          \
39     DEF(Neg, UNARY_OPERATION)          \
40     DEF(Abs, UNARY_OPERATION)          \
41     DEF(Not, UNARY_OPERATION)          \
42     DEF(Sqrt, UNARY_OPERATION)
43 
44 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
45 #define ENCODE_MATH_BINARY_OP_LIST(DEF) \
46     DEF(Add, BINARY_OPERATION)          \
47     DEF(Sub, BINARY_OPERATION)          \
48     DEF(Mul, BINARY_OPERATION)          \
49     DEF(Shl, BINARY_OPERATION)          \
50     DEF(Shr, BINARY_OPERATION)          \
51     DEF(AShr, BINARY_OPERATION)         \
52     DEF(And, BINARY_OPERATION)          \
53     DEF(Or, BINARY_OPERATION)           \
54     DEF(Xor, BINARY_OPERATION)
55 
56 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
57 #define ENCODE_MATH_LIST(DEF)      \
58     ENCODE_MATH_UNARY_OP_LIST(DEF) \
59     ENCODE_MATH_BINARY_OP_LIST(DEF)
60 
61 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
62 #define ENCODE_INST_WITH_SHIFTED_OPERAND(DEF)      \
63     DEF(And, BINARY_SHIFTED_REGISTER_OPERATION)    \
64     DEF(Or, BINARY_SHIFTED_REGISTER_OPERATION)     \
65     DEF(Xor, BINARY_SHIFTED_REGISTER_OPERATION)    \
66     DEF(OrNot, BINARY_SHIFTED_REGISTER_OPERATION)  \
67     DEF(AndNot, BINARY_SHIFTED_REGISTER_OPERATION) \
68     DEF(XorNot, BINARY_SHIFTED_REGISTER_OPERATION) \
69     DEF(Add, BINARY_SHIFTED_REGISTER_OPERATION)    \
70     DEF(Sub, BINARY_SHIFTED_REGISTER_OPERATION)
71 
72 namespace ark::compiler {
73 class Encoder;
74 class CompilerOptions;
75 class RelocationInfo;
76 
77 namespace memory_order {
78 enum Order { ACQUIRE, RELEASE, FULL };
79 }  // namespace memory_order
80 
81 class LabelHolder {
82 public:
83     using LabelId = uintptr_t;
84     static constexpr LabelId INVALID_LABEL = static_cast<uintptr_t>(-1);
85 
LabelHolder(Encoder * enc)86     explicit LabelHolder(Encoder *enc) : enc_ {enc} {};
87     virtual ~LabelHolder() = default;
88 
89     // NOTE (igorban) : hide all this methods in CallConv
90     virtual void CreateLabels(LabelId size) = 0;
91     virtual LabelId CreateLabel() = 0;
92     virtual LabelId Size() = 0;
93 
GetEncoder()94     Encoder *GetEncoder() const
95     {
96         return enc_;
97     }
98 
99     NO_COPY_SEMANTIC(LabelHolder);
100     NO_MOVE_SEMANTIC(LabelHolder);
101 
102 protected:
103     virtual void BindLabel(LabelId) = 0;
104 
105 private:
106     Encoder *enc_ {nullptr};
107     friend Encoder;
108 };
109 
110 class Encoder {
111 public:
112     // Main constructor
Encoder(ArenaAllocator * aa,Arch arch)113     explicit Encoder(ArenaAllocator *aa, Arch arch) : Encoder(aa, arch, false) {}
Encoder(ArenaAllocator * aa,Arch arch,bool jsNumberCast)114     Encoder(ArenaAllocator *aa, Arch arch, bool jsNumberCast)
115         : allocator_(aa), frameLayout_(arch, 0), target_(arch), jsNumberCast_(jsNumberCast)
116     {
117     }
118     virtual ~Encoder() = default;
119 
120     ArenaAllocator *GetAllocator() const;
121     bool IsLabelValid(LabelHolder::LabelId label);
122 
123     Target GetTarget() const;
124     Arch GetArch() const;
125     bool IsJsNumberCast() const;
126     void SetIsJsNumberCast(bool v);
127 
128     /// Print instruction and return next pc
129     virtual size_t DisasmInstr(std::ostream &stream, size_t pc, ssize_t codeOffset) const;
130     virtual void *BufferData() const;
131     virtual size_t BufferSize() const;
132 
133     virtual bool InitMasm();
134 
SetMaxAllocatedBytes(size_t size)135     virtual void SetMaxAllocatedBytes([[maybe_unused]] size_t size) {};
136 
137 // Define default math operations
138 // Encode (dst, src)
139 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
140 #define UNARY_OPERATION(opc)           \
141     virtual void Encode##opc(Reg, Reg) \
142     {                                  \
143         SetFalseResult();              \
144     }
145 
146 // Encode (dst, src0, src1)
147 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
148 #define BINARY_OPERATION(opc)               \
149     virtual void Encode##opc(Reg, Reg, Reg) \
150     {                                       \
151         SetFalseResult();                   \
152     }                                       \
153     virtual void Encode##opc(Reg, Reg, Imm) \
154     {                                       \
155         SetFalseResult();                   \
156     }
157 
158 // Encode (dst, src0, src1)
159 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
160 #define BINARY_SHIFTED_REGISTER_OPERATION(opc) \
161     virtual void Encode##opc(Reg, Reg, Shift)  \
162     {                                          \
163         SetFalseResult();                      \
164     }
165 
166 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
167 #define INST_DEF(OPCODE, MACRO) MACRO(OPCODE)
168 
169     ENCODE_MATH_LIST(INST_DEF)
170     ENCODE_INST_WITH_SHIFTED_OPERAND(INST_DEF)
171 
172 #undef UNARY_OPERATION
173 #undef BINARY_OPERATION
174 #undef BINARY_SHIFTED_REGISTER_OPERATION
175 #undef INST_DEF
176 
177     virtual void EncodeNop();
178 
179     virtual void EncodeAddOverflow(LabelHolder::LabelId id, Reg dst, Reg src0, Reg src1, Condition cc);
180     virtual void EncodeSubOverflow(LabelHolder::LabelId id, Reg dst, Reg src0, Reg src1, Condition cc);
181     virtual void EncodeMulOverflow(LabelHolder::LabelId id, Reg dst, Reg src0, Reg src1, Condition cc);
182     virtual void EncodeNegOverflowAndZero(LabelHolder::LabelId id, Reg dst, Reg src);
183     virtual void EncodeFastPathDynamicCast(Reg dst, Reg src, LabelHolder::LabelId slow);
184     virtual void EncodeCast(Reg dst, bool dstSigned, Reg src, bool srcSigned);
185     virtual void EncodeCastToBool(Reg dst, Reg src);
186     virtual void EncodeMin(Reg dst, bool dstSigned, Reg src0, Reg src1);
187     virtual void EncodeDiv(Reg dst, bool dstSigned, Reg src0, Reg src1);
188     virtual void EncodeMod(Reg dst, bool dstSigned, Reg src0, Reg src1);
189     virtual void EncodeDiv(Reg dst, Reg src0, Imm imm, bool isSigned);
190     virtual void EncodeMod(Reg dst, Reg src0, Imm imm, bool isSigned);
191     virtual void EncodeMax(Reg dst, bool dstSigned, Reg src0, Reg src1);
192     virtual void EncodeMov(Reg dst, Imm src);
193     virtual void EncodeLdr(Reg dst, bool dstSigned, MemRef mem);
194     virtual void EncodeLdrAcquire(Reg dst, bool dstSigned, MemRef mem);
195     virtual void EncodeStr(Reg src, MemRef mem);
196     virtual void EncodeStrRelease(Reg src, MemRef mem);
197     virtual void EncodeLdrExclusive(Reg dst, Reg addr, bool acquire);
198     virtual void EncodeStrExclusive(Reg dst, Reg src, Reg addr, bool release);
199     // zerod high part: [reg.size, 64)
200     virtual void EncodeStrz(Reg src, MemRef mem);
201     virtual void Push(Reg src, MemRef mem);
202     virtual void EncodeSti(int64_t src, uint8_t srcSizeBytes, MemRef mem);
203     virtual void EncodeSti(double src, MemRef mem);
204     virtual void EncodeSti(float src, MemRef mem);
205     // size must be 8, 16,32 or 64
206     virtual void EncodeMemCopy(MemRef memFrom, MemRef memTo, size_t size);
207     // size must be 8, 16,32 or 64
208     // zerod high part: [size, 64)
209     virtual void EncodeMemCopyz(MemRef memFrom, MemRef memTo, size_t size);
210     virtual void EncodeCmp(Reg dst, Reg src0, Reg src1, Condition cc);
211     // Additional check for isnan-comparison
212     virtual void EncodeCompare(Reg dst, Reg src0, Reg src1, Condition cc);
213     virtual void EncodeCompareTest(Reg dst, Reg src0, Reg src1, Condition cc);
214     virtual void EncodeAtomicByteOr(Reg addr, Reg value, bool fastEncoding);
215     struct ArgsCompressedStringCharAt {
216         Reg dst;
217         Reg str;
218         Reg idx;
219         Reg length;
220         Reg tmp;
221         size_t dataOffset;
222         uint8_t shift;
223     };
224     virtual void EncodeCompressedStringCharAt(ArgsCompressedStringCharAt &&args);
225 
226     struct ArgsCompressedStringCharAtI {
227         Reg dst;
228         Reg str;
229         Reg length;
230         size_t dataOffset;
231         uint32_t index;
232         uint8_t shift;
233     };
234     virtual void EncodeCompressedStringCharAtI(ArgsCompressedStringCharAtI &&args);
235     struct ArgsSelect {
236         Reg dst;
237         Reg src0;
238         Reg src1;
239         Reg src2;
240         Reg src3;
241         Condition cc;
242     };
243     virtual void EncodeSelect(ArgsSelect &&args);
244     virtual void EncodeSelectTest(ArgsSelect &&args);
245 
246     struct ArgsSelectImm {
247         Reg dst;
248         Reg src0;
249         Reg src1;
250         Reg src2;
251         Imm imm;
252         Condition cc;
253     };
254     virtual void EncodeSelect(ArgsSelectImm &&args);
255     virtual void EncodeSelectTest(ArgsSelectImm &&args);
256 
257     virtual void EncodeIsInf(Reg dst, Reg src0);
258     virtual void EncodeIsInteger(Reg dst, Reg src0);
259     virtual void EncodeIsSafeInteger(Reg dst, Reg src0);
260     virtual void EncodeReverseBytes(Reg dst, Reg src);
261     virtual void EncodeReverseBits(Reg dst, Reg src);
262     virtual void EncodeReverseHalfWords(Reg dst, Reg src);
263     virtual void EncodeBitCount(Reg dst, Reg src);
264     virtual void EncodeRotate(Reg dst, Reg src1, Reg src2, bool isRor);
265     virtual void EncodeSignum(Reg dst, Reg src);
266     virtual void EncodeCountLeadingZeroBits(Reg dst, Reg src);
267     virtual void EncodeCountTrailingZeroBits(Reg dst, Reg src);
268     virtual void EncodeCeil(Reg dst, Reg src);
269     virtual void EncodeFloor(Reg dst, Reg src);
270     virtual void EncodeRint(Reg dst, Reg src);
271     virtual void EncodeTrunc(Reg dst, Reg src);
272     virtual void EncodeRoundAway(Reg dst, Reg src);
273     virtual void EncodeRoundToPInf(Reg dst, Reg src);
274 
275     virtual void EncodeGetTypeSize(Reg size, Reg type);
276     virtual void EncodeLdp(Reg dst0, Reg dst1, bool dstSigned, MemRef mem);
277     virtual void EncodeStp(Reg src0, Reg src1, MemRef mem);
278     virtual void EncodeMAdd(Reg dst, Reg src0, Reg src1, Reg src2);
279     virtual void EncodeMSub(Reg dst, Reg src0, Reg src1, Reg src2);
280     virtual void EncodeMNeg(Reg dst, Reg src0, Reg src1);
281     virtual void EncodeOrNot(Reg dst, Reg src0, Reg src1);
282     virtual void EncodeAndNot(Reg dst, Reg src0, Reg src1);
283     virtual void EncodeXorNot(Reg dst, Reg src0, Reg src1);
284     virtual void EncodeNeg(Reg dst, Shift src);
285     virtual void EncodeFpToBits(Reg dst, Reg src);
286     virtual void EncodeMoveBitsRaw(Reg dst, Reg src);
287     virtual void EncodeExtractBits(Reg dst, Reg src, Imm imm1, Imm imm2);
288     virtual void EncodeCrc32Update(Reg dst, Reg crcReg, Reg valReg);
289     /**
290      * Encode dummy load from the address [sp + offset].
291      * @param offset offset from the stack pointer register
292      */
293     virtual void EncodeStackOverflowCheck(ssize_t offset);
294     virtual bool IsValid() const;
295     virtual bool GetResult() const;
296     void SetFalseResult();
297     // Encoder builder - implement in target.cpp
298     static Encoder *Create(ArenaAllocator *arenaAllocator, Arch arch, bool printAsm, bool jsNumberCast = false);
299     // For now it is one function for Add/Sub and Cmp, it suits all considered targets (x86, amd64, arm32, arm64).
300     // We probably should revisit this if we add new targets, like Thumb-2 or others.
301     virtual bool CanEncodeImmAddSubCmp(int64_t imm, uint32_t size, bool signedCompare);
302     virtual bool CanEncodeImmMulDivMod(uint64_t imm, uint32_t size);
303     virtual bool CanEncodeImmLogical(uint64_t imm, uint32_t size);
304     virtual bool CanOptimizeImmDivMod(uint64_t imm, bool isSigned) const;
305     virtual bool CanEncodeScale(uint64_t imm, uint32_t size);
306     virtual bool CanEncodeShift(uint32_t size);
307     virtual bool CanEncodeBitCount();
308     virtual bool CanEncodeMAdd();
309     virtual bool CanEncodeMSub();
310     virtual bool CanEncodeMNeg();
311     virtual bool CanEncodeOrNot();
312     virtual bool CanEncodeAndNot();
313     virtual bool CanEncodeXorNot();
314     // Check if encoder is capable of encoding operations where an operand is a register with
315     // a value shifted by shift operation with specified type by some immediate value.
316     virtual bool CanEncodeShiftedOperand(ShiftOpcode opcode, ShiftType shiftType);
317     virtual bool CanEncodeCompressedStringCharAt();
318     virtual bool CanEncodeCompressedStringCharAtI();
319     virtual bool CanEncodeFloatSelect();
320     virtual void EncodeCompareAndSwap(Reg dst, Reg obj, Reg offset, Reg val, Reg newval);
321     virtual void EncodeCompareAndSwap(Reg dst, Reg addr, Reg val, Reg newval);
322     virtual void EncodeUnsafeGetAndSet(Reg dst, Reg obj, Reg offset, Reg val);
323     virtual void EncodeUnsafeGetAndAdd(Reg dst, Reg obj, Reg offset, Reg val, Reg tmp);
324     virtual void EncodeMemoryBarrier(memory_order::Order order);
325     virtual size_t GetCursorOffset() const;
326     virtual void EncodeCompressEightUtf16ToUtf8CharsUsingSimd(Reg srcAddr, Reg dstAddr);
327     virtual void EncodeCompressSixteenUtf16ToUtf8CharsUsingSimd(Reg srcAddr, Reg dstAddr);
328     virtual void EncodeMemCharU8X32UsingSimd(Reg dst, Reg ch, Reg srcAddr, Reg tmp);
329     virtual void EncodeMemCharU16X16UsingSimd(Reg dst, Reg ch, Reg srcAddr, Reg tmp);
330     virtual void EncodeMemCharU8X16UsingSimd(Reg dst, Reg ch, Reg srcAddr, Reg tmp);
331     virtual void EncodeMemCharU16X8UsingSimd(Reg dst, Reg ch, Reg srcAddr, Reg tmp);
332     virtual void EncodeUnsignedExtendBytesToShorts(Reg dst, Reg src);
SetCursorOffset(size_t offset)333     virtual void SetCursorOffset([[maybe_unused]] size_t offset) {}
334     virtual void SaveRegisters(RegMask registers, ssize_t slot, size_t startReg, bool isFp);
335     virtual void LoadRegisters(RegMask registers, ssize_t slot, size_t startReg, bool isFp);
336     /**
337      * Save/load registers to/from the memory.
338      *
339      * If `mask` is empty (all bits are zero), then registers will be saved densely, otherwise place for each register
340      * will be determined according to this mask.
341      * Example: registers' bits = [1, 3, 10], mask's bits = [0, 1, 2, 3, 8, 9, 10, 11]
342      * We can see that mask has the gap in 4-7 bits. So, registers will be saved in the following slots:
343      *      slots: 0   1   2   3   4   5   6   7
344      *      regs :     1       3          10
345      * If the mask would be zero, then the following layout will be used:
346      *      slots: 0   1   2
347      *      regs : 1   3  10
348      *
349      * @param registers mask of registers to be saved
350      * @param is_fp if true, registers are floating point registers
351      * @param slot offset from the `base` register to the destination address (in words)
352      * @param base base register
353      * @param mask determine memory layout for the registers
354      */
355     virtual void SaveRegisters(RegMask registers, bool isFp, ssize_t slot, Reg base, RegMask mask);
356     virtual void LoadRegisters(RegMask registers, bool isFp, ssize_t slot, Reg base, RegMask mask);
357     void PushRegisters(RegMask regs, VRegMask fpRegs, bool isAligned = true);
358     void PopRegisters(RegMask regs, VRegMask fpRegs, bool isAligned = true);
359     virtual void PushRegisters(RegMask registers, bool isFp);
360     virtual void PopRegisters(RegMask registers, bool isFp);
361     RegistersDescription *GetRegfile() const;
362     void SetRegfile(RegistersDescription *regfile);
363     virtual Reg AcquireScratchRegister(TypeInfo type);
364     virtual void AcquireScratchRegister(Reg reg);
365     virtual void ReleaseScratchRegister(Reg reg);
366     virtual bool IsScratchRegisterReleased(Reg reg) const;
367     size_t GetScratchRegistersCount() const;
368     size_t GetScratchRegistersWithLrCount() const;
369     virtual RegMask GetScratchRegistersMask() const;
370     size_t GetScratchFPRegistersCount() const;
371     virtual RegMask GetScratchFpRegistersMask() const;
372     // Get Scratch registers, that currently are not allocated
373     virtual RegMask GetAvailableScratchRegisters() const;
374     // Get Floating Point Scratch registers, that currently are not allocated
375     virtual VRegMask GetAvailableScratchFpRegisters() const;
376     virtual size_t MaxArchInstPerEncoded();
377     virtual void SetRegister(RegMask *mask, VRegMask *vmask, Reg reg);
378     virtual void SetRegister(RegMask *mask, VRegMask *vmask, Reg reg, bool val) const;
379     virtual TypeInfo GetRefType();
380     virtual void Finalize() = 0;
381 
382 public:
383     /// Label-holder interfaces
384     LabelHolder::LabelId CreateLabel();
385     void BindLabel(LabelHolder::LabelId id);
386     virtual LabelHolder *GetLabels() const;
387     virtual size_t GetLabelAddress(LabelHolder::LabelId label) = 0;
388     virtual bool LabelHasLinks(LabelHolder::LabelId label) = 0;
389 
390 public:
391     virtual void MakeCall(RelocationInfo *relocation);
392     virtual void MakeCall(LabelHolder::LabelId id);
393     virtual void MakeCall(const void *entryPoint);
394     virtual void MakeCall(Reg reg);
395     virtual void MakeCall(MemRef entryPoint);
396     virtual void MakeCallAot(intptr_t offset);
397     virtual bool CanMakeCallByOffset(intptr_t offset);
398     virtual void MakeCallByOffset(intptr_t offset);
399     virtual void MakeLoadAotTable(intptr_t offset, Reg reg);
400     virtual void MakeLoadAotTableAddr(intptr_t offset, Reg addr, Reg val);
401 
402     // Encode unconditional branch
403     virtual void EncodeJump(LabelHolder::LabelId id);
404     // Encode jump with compare to zero
405     virtual void EncodeJump(LabelHolder::LabelId id, Reg reg, Condition cond);
406     // Compare reg and immediate and branch
407     virtual void EncodeJump(LabelHolder::LabelId id, Reg reg, Imm imm, Condition c);
408     // Compare two regs and branch
409     virtual void EncodeJump(LabelHolder::LabelId id, Reg r, Reg reg, Condition c);
410     // Compare reg and immediate and branch
411     virtual void EncodeJumpTest(LabelHolder::LabelId id, Reg reg, Imm imm, Condition c);
412     // Compare two regs and branch
413     virtual void EncodeJumpTest(LabelHolder::LabelId id, Reg r, Reg reg, Condition c);
414     // Encode jump by register value
415     virtual void EncodeJump(Reg reg);
416     virtual void EncodeJump(RelocationInfo *relocation);
417 
418     virtual void EncodeBitTestAndBranch(LabelHolder::LabelId id, Reg reg, uint32_t bitPos, bool bitValue);
419 
420     virtual void EncodeAbort();
421     virtual void EncodeReturn();
422 
423     void SetFrameLayout(CFrameLayout fl);
424 
425     const CFrameLayout &GetFrameLayout() const;
426 
427     RegMask GetLiveTmpRegMask();
428 
429     VRegMask GetLiveTmpFpRegMask();
430 
431     void AddRegInLiveMask(Reg reg);
432 
433     void RemoveRegFromLiveMask(Reg reg);
434     void SetCodeOffset(size_t offset);
435 
436     size_t GetCodeOffset() const;
437 
438     void EnableLrAsTempReg(bool value);
439 
440     bool IsLrAsTempRegEnabled() const;
441 
442     bool IsLrAsTempRegEnabledAndReleased() const;
443     NO_COPY_SEMANTIC(Encoder);
444     NO_MOVE_SEMANTIC(Encoder);
445 
446 protected:
447     void SetFrameSize(size_t size);
448 
449     size_t GetFrameSize() const;
450 
451     static constexpr size_t INVALID_OFFSET = std::numeric_limits<size_t>::max();
452 
453     // Max integer that can be represented in float/double without losing precision
MaxIntAsExactFloat()454     constexpr float MaxIntAsExactFloat() const
455     {
456         return static_cast<float>((1U << static_cast<unsigned>(std::numeric_limits<float>::digits)) - 1);
457     }
458 
MaxIntAsExactDouble()459     constexpr double MaxIntAsExactDouble() const
460     {
461         return static_cast<double>((1ULL << static_cast<unsigned>(std::numeric_limits<double>::digits)) - 1);
462     }
463 
CanOptimizeImmDivModCommon(uint64_t imm,bool isSigned)464     static constexpr bool CanOptimizeImmDivModCommon(uint64_t imm, bool isSigned)
465     {
466         if (!isSigned) {
467             return imm > 0U;
468         }
469         auto signedImm = bit_cast<int64_t>(imm);
470         return signedImm <= -2L || signedImm >= 2L;
471     }
472 
473 private:
474     ArenaAllocator *allocator_;
475     RegistersDescription *regfile_ {nullptr};
476     size_t frameSize_ {0};
477 
478     CFrameLayout frameLayout_;
479 
480     RegMask liveTmpRegs_;
481     VRegMask liveTmpFpRegs_;
482 
483     // In case of AOT compilation, this variable specifies offset from the start of the AOT file.
484     // It is needed for accessing to the entrypoints table and AOT table, that lie right before code.
485     size_t codeOffset_ {INVALID_OFFSET};
486 
487     Target target_ {Arch::NONE};
488 
489     bool success_ {true};
490     bool jsNumberCast_ {false};
491     // If true, then ScopedTmpReg can use LR as a temp register.
492     bool enableLrAsTempReg_ {false};
493 };  // Encoder
494 }  // namespace ark::compiler
495 
496 #endif  // COMPILER_OPTIMIZER_CODEGEN_ENCODE_H
497