CodeGenerator-arm64.h (4254B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jit_arm64_CodeGenerator_arm64_h 8 #define jit_arm64_CodeGenerator_arm64_h 9 10 #include "jit/arm64/Assembler-arm64.h" 11 #include "jit/shared/CodeGenerator-shared.h" 12 13 namespace js { 14 namespace jit { 15 16 class CodeGeneratorARM64; 17 class OutOfLineTableSwitch; 18 19 using OutOfLineWasmTruncateCheck = 20 OutOfLineWasmTruncateCheckBase<CodeGeneratorARM64>; 21 22 class CodeGeneratorARM64 : public CodeGeneratorShared { 23 friend class MoveResolverARM64; 24 25 protected: 26 CodeGeneratorARM64(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm, 27 const wasm::CodeMetadata* wasmCodeMeta); 28 29 NonAssertingLabel deoptLabel_; 30 31 MoveOperand toMoveOperand(const LAllocation a) const; 32 33 void bailoutIf(Assembler::Condition condition, LSnapshot* snapshot); 34 void bailoutIfZero(Assembler::Condition condition, ARMRegister rt, 35 LSnapshot* snapshot); 36 void bailoutFrom(Label* label, LSnapshot* snapshot); 37 void bailout(LSnapshot* snapshot); 38 39 template <typename T1, typename T2> 40 void bailoutCmpPtr(Assembler::Condition c, T1 lhs, T2 rhs, 41 LSnapshot* snapshot) { 42 if constexpr (std::is_same_v<T1, Register> && 43 (std::is_same_v<T2, Imm32> || std::is_same_v<T2, Imm64> || 44 std::is_same_v<T2, ImmWord> || std::is_same_v<T2, ImmPtr>)) { 45 if (rhs.value == 0) { 46 if (c == Assembler::Equal) { 47 bailoutIfZero(Assembler::Zero, ARMRegister(lhs, 64), snapshot); 48 return; 49 } 50 if (c == Assembler::NotEqual) { 51 bailoutIfZero(Assembler::NonZero, ARMRegister(lhs, 64), snapshot); 52 return; 53 } 54 } 55 } 56 masm.cmpPtr(lhs, rhs); 57 return bailoutIf(c, snapshot); 58 } 59 template <typename T1, typename T2> 60 void bailoutCmp32(Assembler::Condition c, T1 lhs, T2 rhs, 61 LSnapshot* snapshot) { 62 if constexpr (std::is_same_v<T1, Register> && std::is_same_v<T2, Imm32>) { 63 if (rhs.value == 0) { 64 if (c == Assembler::Equal) { 65 bailoutIfZero(Assembler::Zero, ARMRegister(lhs, 32), snapshot); 66 return; 67 } 68 if (c == Assembler::NotEqual) { 69 bailoutIfZero(Assembler::NonZero, ARMRegister(lhs, 32), snapshot); 70 return; 71 } 72 } 73 } 74 masm.cmp32(lhs, rhs); 75 return bailoutIf(c, snapshot); 76 } 77 template <typename T1, typename T2> 78 void bailoutTest32(Assembler::Condition c, T1 lhs, T2 rhs, 79 LSnapshot* snapshot) { 80 if constexpr (std::is_same_v<T1, Register> && 81 std::is_same_v<T2, Register>) { 82 if (lhs == rhs && (c == Assembler::Zero || c == Assembler::NonZero)) { 83 bailoutIfZero(c, ARMRegister(lhs, 32), snapshot); 84 return; 85 } 86 } 87 masm.test32(lhs, rhs); 88 return bailoutIf(c, snapshot); 89 } 90 void bailoutIfFalseBool(Register reg, LSnapshot* snapshot) { 91 masm.test32(reg, Imm32(0xFF)); 92 return bailoutIf(Assembler::Zero, snapshot); 93 } 94 95 bool generateOutOfLineCode(); 96 97 // Emits a branch that directs control flow to the true block if |cond| is 98 // true, and the false block if |cond| is false. 99 void emitBranch(Assembler::Condition cond, MBasicBlock* ifTrue, 100 MBasicBlock* ifFalse); 101 102 void emitTableSwitchDispatch(MTableSwitch* mir, Register index, 103 Register base); 104 105 void emitBigIntPtrDiv(LBigIntPtrDiv* ins, Register dividend, Register divisor, 106 Register output); 107 void emitBigIntPtrMod(LBigIntPtrMod* ins, Register dividend, Register divisor, 108 Register output); 109 110 void generateInvalidateEpilogue(); 111 112 public: 113 void emitBailoutOOL(LSnapshot* snapshot); 114 115 void visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool); 116 void visitOutOfLineWasmTruncateCheck(OutOfLineWasmTruncateCheck* ool); 117 }; 118 119 using CodeGeneratorSpecific = CodeGeneratorARM64; 120 121 } // namespace jit 122 } // namespace js 123 124 #endif /* jit_arm64_CodeGenerator_arm64_h */