1 /* 2 * Copyright (c) 2022 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 ECMASCRIPT_COMPILER_AARCH64_EXTENDED_ASSEMBLER_H 17 #define ECMASCRIPT_COMPILER_AARCH64_EXTENDED_ASSEMBLER_H 18 19 #include "ecmascript/compiler/assembler/aarch64/assembler_aarch64.h" 20 #include "ecmascript/compiler/assembler/aarch64/extend_assembler.h" 21 #include "ecmascript/frames.h" 22 23 namespace panda::ecmascript::aarch64 { 24 using Label = panda::ecmascript::Label; 25 class CommonCall { 26 public: 27 static constexpr int FRAME_SLOT_SIZE = 8; 28 static constexpr int DOUBLE_SLOT_SIZE = 16; 29 static constexpr int TRIPLE_SLOT_SIZE = 24; 30 static constexpr int QUADRUPLE_SLOT_SIZE = 32; 31 static constexpr int QUINTUPLE_SLOT_SIZE = 40; 32 static constexpr int DECUPLE_SLOT_SIZE = 80; 33 static constexpr int FRAME_SLOT_SIZE_LOG2 = 3; 34 enum BuiltinsLeaveFrameArgId : unsigned {CODE_ADDRESS = 0, ENV, ARGC, ARGV}; GetStackArgOffSetToFp(unsigned argId)35 static inline int64_t GetStackArgOffSetToFp(unsigned argId) 36 { 37 // +--------------------------+ 38 // | argv0 | calltarget , newtARGET, this, .... 39 // +--------------------------+ --- 40 // | argc | ^ 41 // |--------------------------| arguments 42 // | env | | 43 // |--------------------------| | 44 // | codeAddress | | 45 // |--------------------------| | 46 // | returnAddr | | 47 // |--------------------------| Fixed OptimizedBuiltinLeaveFrame 48 // | callsiteFp | | 49 // |--------------------------| | 50 // | frameType | v 51 // +--------------------------+ --- 52 // 16 : 16 means arguments offset to fp 53 return 16 + static_cast<int64_t>(argId) * static_cast<int64_t>(FRAME_SLOT_SIZE); 54 } 55 static void PushUndefinedWithArgc(ExtendedAssembler *assembler, Register glue, Register argc, Register temp, 56 Register fp, Label *next, Label *stackOverflow); 57 static void PushArgsWithArgv(ExtendedAssembler *assembler, Register glue, Register argc, Register argv, 58 Register op, Register fp, Label *next, Label *stackOverflow); 59 static void PushAsmInterpBridgeFrame(ExtendedAssembler *assembler); 60 static void PopAsmInterpBridgeFrame(ExtendedAssembler *assembler); 61 static void StackOverflowCheck(ExtendedAssembler *assembler, Register glue, Register currentSlot, Register numArgs, 62 Register op, Label *stackOverflow); 63 static void PushLeaveFrame(ExtendedAssembler *assembler, Register glue); 64 static void PopLeaveFrame(ExtendedAssembler *assembler); 65 }; 66 67 class OptimizedCall : public CommonCall { 68 public: 69 static void CallRuntime(ExtendedAssembler *assembler); 70 71 static void JSFunctionEntry(ExtendedAssembler *assembler); 72 73 static void OptimizedCallOptimized(ExtendedAssembler *assembler); 74 75 static void CallBuiltinTrampoline(ExtendedAssembler *assembler); 76 77 static void JSProxyCallInternalWithArgV(ExtendedAssembler *assembler); 78 79 static void JSCall(ExtendedAssembler *assembler); 80 81 static void ConstructorJSCall(ExtendedAssembler *assembler); 82 83 static void CallRuntimeWithArgv(ExtendedAssembler *assembler); 84 85 static void JSCallWithArgV(ExtendedAssembler *assembler); 86 87 static void ConstructorJSCallWithArgV(ExtendedAssembler *assembler); 88 89 static void DeoptHandlerAsm(ExtendedAssembler *assembler); 90 91 static void JSCallNew(ExtendedAssembler *assembler); 92 93 static void JSCallNewWithArgV(ExtendedAssembler *assembler); 94 95 static void GenJSCall(ExtendedAssembler *assembler, bool isNew); 96 97 static void GenJSCallWithArgV(ExtendedAssembler *assembler, bool isNew); 98 private: 99 static void DeoptEnterAsmInterp(ExtendedAssembler *assembler); 100 static void JSCallCheck(ExtendedAssembler *assembler, Register jsfunc, Register taggedValue, 101 Label *nonCallable, Label *notJSFunction); 102 static void ThrowNonCallableInternal(ExtendedAssembler *assembler, Register sp); 103 static void CallOptimziedMethodInternal(ExtendedAssembler *assembler, Register jsfunc, Register actualArgC, 104 Register callField, Register sp); 105 static void JSBoundFunctionCallInternal(ExtendedAssembler *assembler, Register glue, 106 Register actualArgC, Register jsfunc, int stubId); 107 static void JSProxyCallInternal(ExtendedAssembler *assembler, Register sp, Register jsfunc); 108 static void OptimizedCallAsmInterpreter(ExtendedAssembler *assembler); 109 static void PushMandatoryJSArgs(ExtendedAssembler *assembler, Register jsfunc, 110 Register thisObj, Register newTarget, Register currentSp); 111 static void PopJSFunctionArgs(ExtendedAssembler *assembler, Register expectedNumArgs, Register actualNumArgs); 112 static void PushJSFunctionEntryFrame (ExtendedAssembler *assembler, Register prevFp); 113 static void PopJSFunctionEntryFrame(ExtendedAssembler *assembler, Register glue); 114 static void PushOptimizedUnfoldArgVFrame(ExtendedAssembler *assembler, Register callSiteSp); 115 static void PopOptimizedUnfoldArgVFrame(ExtendedAssembler *assembler); 116 static void IncreaseStackForArguments(ExtendedAssembler *assembler, Register argC, Register fp); 117 static void PushOptimizedArgsConfigFrame(ExtendedAssembler *assembler); 118 static void PopOptimizedArgsConfigFrame(ExtendedAssembler *assembler); 119 static void PushAsmBridgeFrame(ExtendedAssembler *assembler); 120 static void PopOptimizedFrame(ExtendedAssembler *assembler); 121 static void JSCallInternal(ExtendedAssembler *assembler, Register jsfunc, bool isNew = false); 122 static void ConstructorJSCallInternal(ExtendedAssembler *assembler, Register jsfunc); 123 }; 124 125 class AsmInterpreterCall : public CommonCall { 126 public: 127 static void AsmInterpreterEntry(ExtendedAssembler *assembler); 128 129 static void AsmInterpEntryDispatch(ExtendedAssembler *assembler); 130 131 static void GeneratorReEnterAsmInterp(ExtendedAssembler *assembler); 132 133 static void GeneratorReEnterAsmInterpDispatch(ExtendedAssembler *assembler); 134 135 static void PushCallThisRangeAndDispatch(ExtendedAssembler *assembler); 136 137 static void PushCallRangeAndDispatch(ExtendedAssembler *assembler); 138 139 static void PushCallArgs3AndDispatch(ExtendedAssembler *assembler); 140 141 static void PushCallArgs2AndDispatch(ExtendedAssembler *assembler); 142 143 static void PushCallArg1AndDispatch(ExtendedAssembler *assembler); 144 145 static void PushCallArg0AndDispatch(ExtendedAssembler *assembler); 146 147 static void PushCallThisArg0AndDispatch(ExtendedAssembler *assembler); 148 149 static void PushCallThisArg1AndDispatch(ExtendedAssembler *assembler); 150 151 static void PushCallThisArgs2AndDispatch(ExtendedAssembler *assembler); 152 153 static void PushCallThisArgs3AndDispatch(ExtendedAssembler *assembler); 154 155 static void PushCallThisRangeAndDispatchNative(ExtendedAssembler *assembler); 156 157 static void PushCallRangeAndDispatchNative(ExtendedAssembler *assembler); 158 159 static void PushCallNewAndDispatchNative(ExtendedAssembler *assembler); 160 161 static void PushCallNewAndDispatch(ExtendedAssembler *assembler); 162 163 static void PushCallArgsAndDispatchNative(ExtendedAssembler *assembler); 164 165 static void ResumeRspAndDispatch(ExtendedAssembler *assembler); 166 167 static void ResumeRspAndReturn([[maybe_unused]] ExtendedAssembler *assembler); 168 169 static void ResumeCaughtFrameAndDispatch(ExtendedAssembler *assembler); 170 171 static void ResumeUncaughtFrameAndReturn(ExtendedAssembler *assembler); 172 173 static void CallGetter(ExtendedAssembler *assembler); 174 175 static void CallSetter(ExtendedAssembler *assembler); 176 177 static void CallContainersArgs3(ExtendedAssembler *assembler); 178 179 private: 180 static void PushCallThis(ExtendedAssembler *assembler, JSCallMode mode, Label *stackOverflow); 181 182 static Register GetThisRegsiter(ExtendedAssembler *assembler, JSCallMode mode, Register defaultRegister); 183 static Register GetNewTargetRegsiter(ExtendedAssembler *assembler, JSCallMode mode, Register defaultRegister); 184 185 static void PushVregs(ExtendedAssembler *assembler, Label *stackOverflow); 186 187 static void DispatchCall(ExtendedAssembler *assembler, Register pc, Register newSp, 188 Register acc = INVALID_REG); 189 190 static void CallNativeInternal(ExtendedAssembler *assembler, Register nativeCode); 191 192 static void PushBuiltinFrame(ExtendedAssembler *assembler, Register glue, 193 FrameType type, Register op, Register next); 194 195 static void ThrowStackOverflowExceptionAndReturn(ExtendedAssembler *assembler, Register glue, Register fp, 196 Register op); 197 198 static void PushFrameState(ExtendedAssembler *assembler, Register prevSp, Register fp, Register currentSlot, 199 Register callTarget, Register thisObj, Register method, Register pc, Register op); 200 201 static void JSCallCommonEntry(ExtendedAssembler *assembler, JSCallMode mode); 202 static void JSCallCommonFastPath(ExtendedAssembler *assembler, JSCallMode mode, Label *pushCallThis, 203 Label *stackOverflow); 204 static void JSCallCommonSlowPath(ExtendedAssembler *assembler, JSCallMode mode, 205 Label *fastPathEntry, Label *pushCallThis, Label *stackOverflow); 206 207 static void GetNumVregsFromCallField(ExtendedAssembler *assembler, Register callField, Register numVregs); 208 209 static void GetDeclaredNumArgsFromCallField(ExtendedAssembler *assembler, Register callField, 210 Register declaredNumArgs); 211 212 static void SaveFpAndJumpSize(ExtendedAssembler *assembler, Immediate jumpSize); 213 214 static void PushAsmInterpEntryFrame(ExtendedAssembler *assembler); 215 216 static void PopAsmInterpEntryFrame(ExtendedAssembler *assembler); 217 218 static void PushGeneratorFrameState(ExtendedAssembler *assembler, Register &prevSpRegister, Register &fpRegister, 219 Register ¤tSlotRegister, Register &callTargetRegister, Register &thisRegister, Register &methodRegister, 220 Register &contextRegister, Register &pcRegister, Register &operatorRegister); 221 222 static void CallBCStub(ExtendedAssembler *assembler, Register &newSp, Register &glue, 223 Register &method, Register &pc, Register &temp); 224 225 static void CallNativeEntry(ExtendedAssembler *assembler); 226 227 static void CallNativeWithArgv(ExtendedAssembler *assembler, bool callNew); 228 friend class OptimizedCall; 229 }; 230 } // namespace panda::ecmascript::x64 231 #endif // ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_X64_H 232