• 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 EncodeUnsignedExtendBytesToShorts(Reg dst, Reg src);
SetCursorOffset(size_t offset)329     virtual void SetCursorOffset([[maybe_unused]] size_t offset) {}
330     virtual void SaveRegisters(RegMask registers, ssize_t slot, size_t startReg, bool isFp);
331     virtual void LoadRegisters(RegMask registers, ssize_t slot, size_t startReg, bool isFp);
332     /**
333      * Save/load registers to/from the memory.
334      *
335      * If `mask` is empty (all bits are zero), then registers will be saved densely, otherwise place for each register
336      * will be determined according to this mask.
337      * Example: registers' bits = [1, 3, 10], mask's bits = [0, 1, 2, 3, 8, 9, 10, 11]
338      * We can see that mask has the gap in 4-7 bits. So, registers will be saved in the following slots:
339      *      slots: 0   1   2   3   4   5   6   7
340      *      regs :     1       3          10
341      * If the mask would be zero, then the following layout will be used:
342      *      slots: 0   1   2
343      *      regs : 1   3  10
344      *
345      * @param registers mask of registers to be saved
346      * @param is_fp if true, registers are floating point registers
347      * @param slot offset from the `base` register to the destination address (in words)
348      * @param base base register
349      * @param mask determine memory layout for the registers
350      */
351     virtual void SaveRegisters(RegMask registers, bool isFp, ssize_t slot, Reg base, RegMask mask);
352     virtual void LoadRegisters(RegMask registers, bool isFp, ssize_t slot, Reg base, RegMask mask);
353     void PushRegisters(RegMask regs, VRegMask fpRegs, bool isAligned = true);
354     void PopRegisters(RegMask regs, VRegMask fpRegs, bool isAligned = true);
355     virtual void PushRegisters(RegMask registers, bool isFp);
356     virtual void PopRegisters(RegMask registers, bool isFp);
357     RegistersDescription *GetRegfile() const;
358     void SetRegfile(RegistersDescription *regfile);
359     virtual Reg AcquireScratchRegister(TypeInfo type);
360     virtual void AcquireScratchRegister(Reg reg);
361     virtual void ReleaseScratchRegister(Reg reg);
362     virtual bool IsScratchRegisterReleased(Reg reg) const;
363     size_t GetScratchRegistersCount() const;
364     size_t GetScratchRegistersWithLrCount() const;
365     virtual RegMask GetScratchRegistersMask() const;
366     size_t GetScratchFPRegistersCount() const;
367     virtual RegMask GetScratchFpRegistersMask() const;
368     // Get Scratch registers, that currently are not allocated
369     virtual RegMask GetAvailableScratchRegisters() const;
370     // Get Floating Point Scratch registers, that currently are not allocated
371     virtual VRegMask GetAvailableScratchFpRegisters() const;
372     virtual size_t MaxArchInstPerEncoded();
373     virtual void SetRegister(RegMask *mask, VRegMask *vmask, Reg reg);
374     virtual void SetRegister(RegMask *mask, VRegMask *vmask, Reg reg, bool val) const;
375     virtual TypeInfo GetRefType();
376     virtual void Finalize() = 0;
377 
378 public:
379     /// Label-holder interfaces
380     LabelHolder::LabelId CreateLabel();
381     void BindLabel(LabelHolder::LabelId id);
382     virtual LabelHolder *GetLabels() const;
383     virtual size_t GetLabelAddress(LabelHolder::LabelId label) = 0;
384     virtual bool LabelHasLinks(LabelHolder::LabelId label) = 0;
385 
386 public:
387     virtual void MakeCall(RelocationInfo *relocation);
388     virtual void MakeCall(LabelHolder::LabelId id);
389     virtual void MakeCall(const void *entryPoint);
390     virtual void MakeCall(Reg reg);
391     virtual void MakeCall(MemRef entryPoint);
392     virtual void MakeCallAot(intptr_t offset);
393     virtual bool CanMakeCallByOffset(intptr_t offset);
394     virtual void MakeCallByOffset(intptr_t offset);
395     virtual void MakeLoadAotTable(intptr_t offset, Reg reg);
396     virtual void MakeLoadAotTableAddr(intptr_t offset, Reg addr, Reg val);
397 
398     // Encode unconditional branch
399     virtual void EncodeJump(LabelHolder::LabelId id);
400     // Encode jump with compare to zero
401     virtual void EncodeJump(LabelHolder::LabelId id, Reg reg, Condition cond);
402     // Compare reg and immediate and branch
403     virtual void EncodeJump(LabelHolder::LabelId id, Reg reg, Imm imm, Condition c);
404     // Compare two regs and branch
405     virtual void EncodeJump(LabelHolder::LabelId id, Reg r, Reg reg, Condition c);
406     // Compare reg and immediate and branch
407     virtual void EncodeJumpTest(LabelHolder::LabelId id, Reg reg, Imm imm, Condition c);
408     // Compare two regs and branch
409     virtual void EncodeJumpTest(LabelHolder::LabelId id, Reg r, Reg reg, Condition c);
410     // Encode jump by register value
411     virtual void EncodeJump(Reg reg);
412     virtual void EncodeJump(RelocationInfo *relocation);
413 
414     virtual void EncodeBitTestAndBranch(LabelHolder::LabelId id, Reg reg, uint32_t bitPos, bool bitValue);
415 
416     virtual void EncodeAbort();
417     virtual void EncodeReturn();
418 
419     void SetFrameLayout(CFrameLayout fl);
420 
421     const CFrameLayout &GetFrameLayout() const;
422 
423     RegMask GetLiveTmpRegMask();
424 
425     VRegMask GetLiveTmpFpRegMask();
426 
427     void AddRegInLiveMask(Reg reg);
428 
429     void RemoveRegFromLiveMask(Reg reg);
430     void SetCodeOffset(size_t offset);
431 
432     size_t GetCodeOffset() const;
433 
434     void EnableLrAsTempReg(bool value);
435 
436     bool IsLrAsTempRegEnabled() const;
437 
438     bool IsLrAsTempRegEnabledAndReleased() const;
439     NO_COPY_SEMANTIC(Encoder);
440     NO_MOVE_SEMANTIC(Encoder);
441 
442 protected:
443     void SetFrameSize(size_t size);
444 
445     size_t GetFrameSize() const;
446 
447     static constexpr size_t INVALID_OFFSET = std::numeric_limits<size_t>::max();
448 
449     // Max integer that can be represented in float/double without losing precision
MaxIntAsExactFloat()450     constexpr float MaxIntAsExactFloat() const
451     {
452         return static_cast<float>((1U << static_cast<unsigned>(std::numeric_limits<float>::digits)) - 1);
453     }
454 
MaxIntAsExactDouble()455     constexpr double MaxIntAsExactDouble() const
456     {
457         return static_cast<double>((1ULL << static_cast<unsigned>(std::numeric_limits<double>::digits)) - 1);
458     }
459 
CanOptimizeImmDivModCommon(uint64_t imm,bool isSigned)460     static constexpr bool CanOptimizeImmDivModCommon(uint64_t imm, bool isSigned)
461     {
462         if (!isSigned) {
463             return imm > 0U;
464         }
465         auto signedImm = bit_cast<int64_t>(imm);
466         return signedImm <= -2L || signedImm >= 2L;
467     }
468 
469 private:
470     ArenaAllocator *allocator_;
471     RegistersDescription *regfile_ {nullptr};
472     size_t frameSize_ {0};
473 
474     CFrameLayout frameLayout_;
475 
476     RegMask liveTmpRegs_;
477     VRegMask liveTmpFpRegs_;
478 
479     // In case of AOT compilation, this variable specifies offset from the start of the AOT file.
480     // It is needed for accessing to the entrypoints table and AOT table, that lie right before code.
481     size_t codeOffset_ {INVALID_OFFSET};
482 
483     Target target_ {Arch::NONE};
484 
485     bool success_ {true};
486     bool jsNumberCast_ {false};
487     // If true, then ScopedTmpReg can use LR as a temp register.
488     bool enableLrAsTempReg_ {false};
489 };  // Encoder
490 }  // namespace ark::compiler
491 
492 #endif  // COMPILER_OPTIMIZER_CODEGEN_ENCODE_H
493