1 /* 2 * Copyright (c) 2021-2025 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 EncodeJsDoubleToCharCast(Reg dst, Reg src); 185 virtual void EncodeJsDoubleToCharCast(Reg dst, Reg src, Reg tmp, uint32_t failureResult); 186 virtual void EncodeCast(Reg dst, bool dstSigned, Reg src, bool srcSigned); 187 virtual void EncodeCastToBool(Reg dst, Reg src); 188 virtual void EncodeMin(Reg dst, bool dstSigned, Reg src0, Reg src1); 189 virtual void EncodeDiv(Reg dst, bool dstSigned, Reg src0, Reg src1); 190 virtual void EncodeMod(Reg dst, bool dstSigned, Reg src0, Reg src1); 191 virtual void EncodeDiv(Reg dst, Reg src0, Imm imm, bool isSigned); 192 virtual void EncodeMod(Reg dst, Reg src0, Imm imm, bool isSigned); 193 virtual void EncodeMax(Reg dst, bool dstSigned, Reg src0, Reg src1); 194 virtual void EncodeMov(Reg dst, Imm src); 195 virtual void EncodeLdr(Reg dst, bool dstSigned, MemRef mem); 196 virtual void EncodeLdrAcquire(Reg dst, bool dstSigned, MemRef mem); 197 virtual void EncodeStr(Reg src, MemRef mem); 198 virtual void EncodeStrRelease(Reg src, MemRef mem); 199 virtual void EncodeLdrExclusive(Reg dst, Reg addr, bool acquire); 200 virtual void EncodeStrExclusive(Reg dst, Reg src, Reg addr, bool release); 201 // zerod high part: [reg.size, 64) 202 virtual void EncodeStrz(Reg src, MemRef mem); 203 virtual void Push(Reg src, MemRef mem); 204 virtual void EncodeSti(int64_t src, uint8_t srcSizeBytes, MemRef mem); 205 virtual void EncodeSti(double src, MemRef mem); 206 virtual void EncodeSti(float src, MemRef mem); 207 // size must be 8, 16,32 or 64 208 virtual void EncodeMemCopy(MemRef memFrom, MemRef memTo, size_t size); 209 // size must be 8, 16,32 or 64 210 // zerod high part: [size, 64) 211 virtual void EncodeMemCopyz(MemRef memFrom, MemRef memTo, size_t size); 212 virtual void EncodeCmp(Reg dst, Reg src0, Reg src1, Condition cc); 213 // Additional check for isnan-comparison 214 virtual void EncodeCompare(Reg dst, Reg src0, Reg src1, Condition cc); 215 virtual void EncodeCompareTest(Reg dst, Reg src0, Reg src1, Condition cc); 216 virtual void EncodeAtomicByteOr(Reg addr, Reg value, bool fastEncoding); 217 struct ArgsCompressedStringCharAt { 218 Reg dst; 219 Reg str; 220 Reg idx; 221 Reg length; 222 Reg tmp; 223 size_t dataOffset; 224 uint8_t shift; 225 }; 226 virtual void EncodeCompressedStringCharAt(ArgsCompressedStringCharAt &&args); 227 228 struct ArgsCompressedStringCharAtI { 229 Reg dst; 230 Reg str; 231 Reg length; 232 size_t dataOffset; 233 uint32_t index; 234 uint8_t shift; 235 }; 236 virtual void EncodeCompressedStringCharAtI(ArgsCompressedStringCharAtI &&args); 237 struct ArgsSelect { 238 Reg dst; 239 Reg src0; 240 Reg src1; 241 Reg src2; 242 Reg src3; 243 Condition cc; 244 }; 245 virtual void EncodeSelect(ArgsSelect &&args); 246 virtual void EncodeSelectTest(ArgsSelect &&args); 247 248 struct ArgsSelectImm { 249 Reg dst; 250 Reg src0; 251 Reg src1; 252 Reg src2; 253 Imm imm; 254 Condition cc; 255 }; 256 virtual void EncodeSelect(ArgsSelectImm &&args); 257 virtual void EncodeSelectTest(ArgsSelectImm &&args); 258 259 virtual void EncodeIsInf(Reg dst, Reg src0); 260 virtual void EncodeIsInteger(Reg dst, Reg src0); 261 virtual void EncodeIsSafeInteger(Reg dst, Reg src0); 262 virtual void EncodeReverseBytes(Reg dst, Reg src); 263 virtual void EncodeReverseBits(Reg dst, Reg src); 264 virtual void EncodeReverseHalfWords(Reg dst, Reg src); 265 virtual void EncodeBitCount(Reg dst, Reg src); 266 virtual void EncodeRotate(Reg dst, Reg src1, Reg src2, bool isRor); 267 virtual void EncodeSignum(Reg dst, Reg src); 268 virtual void EncodeCountLeadingZeroBits(Reg dst, Reg src); 269 virtual void EncodeCountTrailingZeroBits(Reg dst, Reg src); 270 virtual void EncodeCeil(Reg dst, Reg src); 271 virtual void EncodeFloor(Reg dst, Reg src); 272 virtual void EncodeRint(Reg dst, Reg src); 273 virtual void EncodeTrunc(Reg dst, Reg src); 274 virtual void EncodeRoundAway(Reg dst, Reg src); 275 virtual void EncodeRoundToPInfReturnFloat(Reg dst, Reg src); 276 virtual void EncodeRoundToPInfReturnScalar(Reg dst, Reg src); 277 278 virtual void EncodeGetTypeSize(Reg size, Reg type); 279 virtual void EncodeLdp(Reg dst0, Reg dst1, bool dstSigned, MemRef mem); 280 virtual void EncodeStp(Reg src0, Reg src1, MemRef mem); 281 virtual void EncodeMAdd(Reg dst, Reg src0, Reg src1, Reg src2); 282 virtual void EncodeMSub(Reg dst, Reg src0, Reg src1, Reg src2); 283 virtual void EncodeMNeg(Reg dst, Reg src0, Reg src1); 284 virtual void EncodeOrNot(Reg dst, Reg src0, Reg src1); 285 virtual void EncodeAndNot(Reg dst, Reg src0, Reg src1); 286 virtual void EncodeXorNot(Reg dst, Reg src0, Reg src1); 287 virtual void EncodeNeg(Reg dst, Shift src); 288 virtual void EncodeFpToBits(Reg dst, Reg src); 289 virtual void EncodeMoveBitsRaw(Reg dst, Reg src); 290 virtual void EncodeExtractBits(Reg dst, Reg src, Imm imm1, Imm imm2); 291 virtual void EncodeCrc32Update(Reg dst, Reg crcReg, Reg valReg); 292 virtual void EncodeGetCurrentPc(Reg dst); 293 /** 294 * Encode dummy load from the address [sp + offset]. 295 * @param offset offset from the stack pointer register 296 */ 297 virtual void EncodeStackOverflowCheck(ssize_t offset); 298 virtual bool IsValid() const; 299 virtual bool GetResult() const; 300 void SetFalseResult(); 301 // Encoder builder - implement in target.cpp 302 static Encoder *Create(ArenaAllocator *arenaAllocator, Arch arch, bool printAsm, bool jsNumberCast = false); 303 // For now it is one function for Add/Sub and Cmp, it suits all considered targets (x86, amd64, arm32, arm64). 304 // We probably should revisit this if we add new targets, like Thumb-2 or others. 305 virtual bool CanEncodeImmAddSubCmp(int64_t imm, uint32_t size, bool signedCompare); 306 virtual bool CanEncodeImmMulDivMod(uint64_t imm, uint32_t size); 307 virtual bool CanEncodeImmLogical(uint64_t imm, uint32_t size); 308 virtual bool CanOptimizeImmDivMod(uint64_t imm, bool isSigned) const; 309 virtual bool CanEncodeScale(uint64_t imm, uint32_t size); 310 virtual bool CanEncodeShift(uint32_t size); 311 virtual bool CanEncodeBitCount(); 312 virtual bool CanEncodeMAdd(); 313 virtual bool CanEncodeMSub(); 314 virtual bool CanEncodeMNeg(); 315 virtual bool CanEncodeOrNot(); 316 virtual bool CanEncodeAndNot(); 317 virtual bool CanEncodeXorNot(); 318 // Check if encoder is capable of encoding operations where an operand is a register with 319 // a value shifted by shift operation with specified type by some immediate value. 320 virtual bool CanEncodeShiftedOperand(ShiftOpcode opcode, ShiftType shiftType); 321 virtual bool CanEncodeCompressedStringCharAt(); 322 virtual bool CanEncodeCompressedStringCharAtI(); 323 virtual bool CanEncodeFloatSelect(); 324 virtual void EncodeCompareAndSwap(Reg dst, Reg obj, Reg offset, Reg val, Reg newval); 325 virtual void EncodeCompareAndSwap(Reg dst, Reg addr, Reg val, Reg newval); 326 virtual void EncodeUnsafeGetAndSet(Reg dst, Reg obj, Reg offset, Reg val); 327 virtual void EncodeUnsafeGetAndAdd(Reg dst, Reg obj, Reg offset, Reg val, Reg tmp); 328 virtual void EncodeMemoryBarrier(memory_order::Order order); 329 virtual size_t GetCursorOffset() const; 330 virtual void EncodeCompressEightUtf16ToUtf8CharsUsingSimd(Reg srcAddr, Reg dstAddr); 331 virtual void EncodeCompressSixteenUtf16ToUtf8CharsUsingSimd(Reg srcAddr, Reg dstAddr); 332 virtual void EncodeMemCharU8X32UsingSimd(Reg dst, Reg ch, Reg srcAddr, Reg tmp); 333 virtual void EncodeMemCharU16X16UsingSimd(Reg dst, Reg ch, Reg srcAddr, Reg tmp); 334 virtual void EncodeMemCharU8X16UsingSimd(Reg dst, Reg ch, Reg srcAddr, Reg tmp); 335 virtual void EncodeMemCharU16X8UsingSimd(Reg dst, Reg ch, Reg srcAddr, Reg tmp); 336 virtual void EncodeUnsignedExtendBytesToShorts(Reg dst, Reg src); SetCursorOffset(size_t offset)337 virtual void SetCursorOffset([[maybe_unused]] size_t offset) {} 338 virtual void SaveRegisters(RegMask registers, ssize_t slot, size_t startReg, bool isFp); 339 virtual void LoadRegisters(RegMask registers, ssize_t slot, size_t startReg, bool isFp); 340 /** 341 * Save/load registers to/from the memory. 342 * 343 * If `mask` is empty (all bits are zero), then registers will be saved densely, otherwise place for each register 344 * will be determined according to this mask. 345 * Example: registers' bits = [1, 3, 10], mask's bits = [0, 1, 2, 3, 8, 9, 10, 11] 346 * We can see that mask has the gap in 4-7 bits. So, registers will be saved in the following slots: 347 * slots: 0 1 2 3 4 5 6 7 348 * regs : 1 3 10 349 * If the mask would be zero, then the following layout will be used: 350 * slots: 0 1 2 351 * regs : 1 3 10 352 * 353 * @param registers mask of registers to be saved 354 * @param is_fp if true, registers are floating point registers 355 * @param slot offset from the `base` register to the destination address (in words) 356 * @param base base register 357 * @param mask determine memory layout for the registers 358 */ 359 virtual void SaveRegisters(RegMask registers, bool isFp, ssize_t slot, Reg base, RegMask mask); 360 virtual void LoadRegisters(RegMask registers, bool isFp, ssize_t slot, Reg base, RegMask mask); 361 void PushRegisters(RegMask regs, VRegMask fpRegs, bool isAligned = true); 362 void PopRegisters(RegMask regs, VRegMask fpRegs, bool isAligned = true); 363 virtual void PushRegisters(RegMask registers, bool isFp); 364 virtual void PopRegisters(RegMask registers, bool isFp); 365 RegistersDescription *GetRegfile() const; 366 void SetRegfile(RegistersDescription *regfile); 367 virtual Reg AcquireScratchRegister(TypeInfo type); 368 virtual void AcquireScratchRegister(Reg reg); 369 virtual void ReleaseScratchRegister(Reg reg); 370 virtual bool IsScratchRegisterReleased(Reg reg) const; 371 size_t GetScratchRegistersCount() const; 372 size_t GetScratchRegistersWithLrCount() const; 373 virtual RegMask GetScratchRegistersMask() const; 374 size_t GetScratchFPRegistersCount() const; 375 virtual RegMask GetScratchFpRegistersMask() const; 376 // Get Scratch registers, that currently are not allocated 377 virtual RegMask GetAvailableScratchRegisters() const; 378 // Get Floating Point Scratch registers, that currently are not allocated 379 virtual VRegMask GetAvailableScratchFpRegisters() const; 380 virtual size_t MaxArchInstPerEncoded(); 381 virtual void SetRegister(RegMask *mask, VRegMask *vmask, Reg reg); 382 virtual void SetRegister(RegMask *mask, VRegMask *vmask, Reg reg, bool val) const; 383 virtual TypeInfo GetRefType(); 384 virtual void Finalize() = 0; 385 386 public: 387 /// Label-holder interfaces 388 LabelHolder::LabelId CreateLabel(); 389 void BindLabel(LabelHolder::LabelId id); 390 virtual LabelHolder *GetLabels() const; 391 virtual size_t GetLabelAddress(LabelHolder::LabelId label) = 0; 392 virtual bool LabelHasLinks(LabelHolder::LabelId label) = 0; 393 394 public: 395 virtual void MakeCall(RelocationInfo *relocation); 396 virtual void MakeCall(LabelHolder::LabelId id); 397 virtual void MakeCall(const void *entryPoint); 398 virtual void MakeCall(Reg reg); 399 virtual void MakeCall(MemRef entryPoint); 400 virtual void MakeCallAot(intptr_t offset); 401 virtual bool CanMakeCallByOffset(intptr_t offset); 402 virtual void MakeCallByOffset(intptr_t offset); 403 virtual void MakeLoadAotTable(intptr_t offset, Reg reg); 404 virtual void MakeLoadAotTableAddr(intptr_t offset, Reg addr, Reg val); 405 406 // Encode unconditional branch 407 virtual void EncodeJump(LabelHolder::LabelId id); 408 // Encode jump with compare to zero 409 virtual void EncodeJump(LabelHolder::LabelId id, Reg reg, Condition cond); 410 // Compare reg and immediate and branch 411 virtual void EncodeJump(LabelHolder::LabelId id, Reg reg, Imm imm, Condition c); 412 // Compare two regs and branch 413 virtual void EncodeJump(LabelHolder::LabelId id, Reg r, Reg reg, Condition c); 414 // Compare reg and immediate and branch 415 virtual void EncodeJumpTest(LabelHolder::LabelId id, Reg reg, Imm imm, Condition c); 416 // Compare two regs and branch 417 virtual void EncodeJumpTest(LabelHolder::LabelId id, Reg r, Reg reg, Condition c); 418 // Encode jump by register value 419 virtual void EncodeJump(Reg reg); 420 virtual void EncodeJump(RelocationInfo *relocation); 421 422 virtual void EncodeBitTestAndBranch(LabelHolder::LabelId id, Reg reg, uint32_t bitPos, bool bitValue); 423 424 virtual void EncodeAbort(); 425 virtual void EncodeReturn(); 426 427 void SetFrameLayout(CFrameLayout fl); 428 429 const CFrameLayout &GetFrameLayout() const; 430 431 RegMask GetLiveTmpRegMask(); 432 433 VRegMask GetLiveTmpFpRegMask(); 434 435 void AddRegInLiveMask(Reg reg); 436 437 void RemoveRegFromLiveMask(Reg reg); 438 void SetCodeOffset(size_t offset); 439 440 size_t GetCodeOffset() const; 441 442 void EnableLrAsTempReg(bool value); 443 444 bool IsLrAsTempRegEnabled() const; 445 446 bool IsLrAsTempRegEnabledAndReleased() const; 447 NO_COPY_SEMANTIC(Encoder); 448 NO_MOVE_SEMANTIC(Encoder); 449 450 protected: 451 void SetFrameSize(size_t size); 452 453 size_t GetFrameSize() const; 454 455 static constexpr size_t INVALID_OFFSET = std::numeric_limits<size_t>::max(); 456 457 // Max integer that can be represented in float/double without losing precision MaxIntAsExactFloat()458 constexpr float MaxIntAsExactFloat() const 459 { 460 return static_cast<float>((1U << static_cast<unsigned>(std::numeric_limits<float>::digits)) - 1); 461 } 462 MaxIntAsExactDouble()463 constexpr double MaxIntAsExactDouble() const 464 { 465 return static_cast<double>((1ULL << static_cast<unsigned>(std::numeric_limits<double>::digits)) - 1); 466 } 467 CanOptimizeImmDivModCommon(uint64_t imm,bool isSigned)468 static constexpr bool CanOptimizeImmDivModCommon(uint64_t imm, bool isSigned) 469 { 470 if (!isSigned) { 471 return imm > 0U; 472 } 473 auto signedImm = bit_cast<int64_t>(imm); 474 return signedImm <= -2L || signedImm >= 2L; 475 } 476 477 private: 478 ArenaAllocator *allocator_; 479 RegistersDescription *regfile_ {nullptr}; 480 size_t frameSize_ {0}; 481 482 CFrameLayout frameLayout_; 483 484 RegMask liveTmpRegs_; 485 VRegMask liveTmpFpRegs_; 486 487 // In case of AOT compilation, this variable specifies offset from the start of the AOT file. 488 // It is needed for accessing to the entrypoints table and AOT table, that lie right before code. 489 size_t codeOffset_ {INVALID_OFFSET}; 490 491 Target target_ {Arch::NONE}; 492 493 bool success_ {true}; 494 bool jsNumberCast_ {false}; 495 // If true, then ScopedTmpReg can use LR as a temp register. 496 bool enableLrAsTempReg_ {false}; 497 }; // Encoder 498 } // namespace ark::compiler 499 500 #endif // COMPILER_OPTIMIZER_CODEGEN_ENCODE_H 501