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