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 #include "ecmascript/compiler/assembler_module.h" 17 18 #include "ecmascript/compiler/assembler/aarch64/assembler_aarch64.h" 19 #include "ecmascript/compiler/assembler/x64/assembler_x64.h" 20 #include "ecmascript/compiler/call_signature.h" 21 #include "ecmascript/compiler/circuit_builder.h" 22 #include "ecmascript/compiler/trampoline/aarch64/common_call.h" 23 #include "ecmascript/compiler/trampoline/x64/common_call.h" 24 #include "ecmascript/compiler/rt_call_signature.h" 25 #include "libpandafile/bytecode_instruction-inl.h" 26 27 namespace panda::ecmascript::kungfu { Run(const CompilationConfig * cfg,Chunk * chunk)28void AssemblerModule::Run(const CompilationConfig *cfg, Chunk* chunk) 29 { 30 SetUpForAsmStubs(); 31 if (cfg->IsAmd64()) { 32 GenerateStubsX64(chunk); 33 } else if (cfg->IsAArch64()) { 34 GenerateStubsAarch64(chunk); 35 } else { 36 UNREACHABLE(); 37 } 38 } 39 GenerateStubsX64(Chunk * chunk)40void AssemblerModule::GenerateStubsX64(Chunk* chunk) 41 { 42 x64::ExtendedAssembler assembler(chunk, this); 43 LOG_COMPILER(INFO) << "compiling asm stubs"; 44 for (size_t i = 0; i < asmCallSigns_.size(); i++) { 45 auto cs = asmCallSigns_[i]; 46 ASSERT(cs->HasConstructor()); 47 LOG_COMPILER(INFO) << "Stub Name: " << cs->GetName(); 48 AssemblerStub *stub = static_cast<AssemblerStub*>( 49 cs->GetConstructor()(nullptr)); 50 stub->GenerateX64(&assembler); 51 delete stub; 52 } 53 buffer_ = assembler.GetBegin(); 54 bufferSize_ = assembler.GetCurrentPosition(); 55 } 56 GenerateStubsAarch64(Chunk * chunk)57void AssemblerModule::GenerateStubsAarch64(Chunk* chunk) 58 { 59 aarch64::ExtendedAssembler assembler(chunk, this); 60 LOG_COMPILER(INFO) << "compiling asm stubs"; 61 for (size_t i = 0; i < asmCallSigns_.size(); i++) { 62 auto cs = asmCallSigns_[i]; 63 ASSERT(cs->HasConstructor()); 64 LOG_COMPILER(INFO) << "Stub Name: " << cs->GetName(); 65 AssemblerStub *stub = static_cast<AssemblerStub*>( 66 cs->GetConstructor()(nullptr)); 67 stub->GenerateAarch64(&assembler); 68 delete stub; 69 } 70 buffer_ = assembler.GetBegin(); 71 bufferSize_ = assembler.GetCurrentPosition(); 72 } 73 SetUpForAsmStubs()74void AssemblerModule::SetUpForAsmStubs() 75 { 76 RuntimeStubCSigns::GetASMCSigns(asmCallSigns_); 77 for (auto cs : asmCallSigns_) { 78 symbolTable_[cs->GetID()] = new panda::ecmascript::Label(); 79 } 80 } 81 GetArgcFromJSCallMode(JSCallMode mode)82int AssemblerModule::GetArgcFromJSCallMode(JSCallMode mode) 83 { 84 switch (mode) { 85 case JSCallMode::CALL_ARG0: 86 case JSCallMode::CALL_THIS_ARG0: 87 case JSCallMode::DEPRECATED_CALL_ARG0: 88 return 0; 89 case JSCallMode::CALL_ARG1: 90 case JSCallMode::CALL_THIS_ARG1: 91 case JSCallMode::DEPRECATED_CALL_ARG1: 92 return 1; 93 case JSCallMode::CALL_ARG2: 94 case JSCallMode::CALL_THIS_ARG2: 95 case JSCallMode::DEPRECATED_CALL_ARG2: 96 return 2; // 2: arg2 97 case JSCallMode::CALL_ARG3: 98 case JSCallMode::CALL_THIS_ARG3: 99 case JSCallMode::DEPRECATED_CALL_ARG3: 100 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN: 101 return 3; // 3: arg3 102 case JSCallMode::CALL_THIS_WITH_ARGV: 103 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV: 104 case JSCallMode::CALL_WITH_ARGV: 105 case JSCallMode::DEPRECATED_CALL_WITH_ARGV: 106 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 107 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 108 case JSCallMode::CALL_ENTRY: 109 case JSCallMode::CALL_FROM_AOT: 110 return -1; 111 case JSCallMode::CALL_GETTER: 112 return 0; 113 case JSCallMode::CALL_SETTER: 114 return 1; 115 default: 116 UNREACHABLE(); 117 } 118 } 119 IsCallNew(JSCallMode mode)120bool AssemblerModule::IsCallNew(JSCallMode mode) 121 { 122 switch (mode) { 123 case JSCallMode::CALL_ARG0: 124 case JSCallMode::CALL_THIS_ARG0: 125 case JSCallMode::DEPRECATED_CALL_ARG0: 126 case JSCallMode::CALL_ARG1: 127 case JSCallMode::CALL_THIS_ARG1: 128 case JSCallMode::DEPRECATED_CALL_ARG1: 129 case JSCallMode::CALL_ARG2: 130 case JSCallMode::CALL_THIS_ARG2: 131 case JSCallMode::DEPRECATED_CALL_ARG2: 132 case JSCallMode::CALL_ARG3: 133 case JSCallMode::CALL_THIS_ARG3: 134 case JSCallMode::DEPRECATED_CALL_ARG3: 135 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV: 136 case JSCallMode::DEPRECATED_CALL_WITH_ARGV: 137 case JSCallMode::CALL_THIS_WITH_ARGV: 138 case JSCallMode::CALL_WITH_ARGV: 139 case JSCallMode::CALL_GETTER: 140 case JSCallMode::CALL_SETTER: 141 case JSCallMode::CALL_ENTRY: 142 case JSCallMode::CALL_FROM_AOT: 143 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN: 144 return false; 145 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 146 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 147 return true; 148 default: 149 UNREACHABLE(); 150 } 151 return false; 152 } 153 JSModeHaveThisArg(JSCallMode mode)154bool AssemblerModule::JSModeHaveThisArg(JSCallMode mode) 155 { 156 switch (mode) { 157 case JSCallMode::CALL_ARG0: 158 case JSCallMode::CALL_ARG1: 159 case JSCallMode::CALL_ARG2: 160 case JSCallMode::CALL_ARG3: 161 case JSCallMode::DEPRECATED_CALL_ARG0: 162 case JSCallMode::DEPRECATED_CALL_ARG1: 163 case JSCallMode::DEPRECATED_CALL_ARG2: 164 case JSCallMode::DEPRECATED_CALL_ARG3: 165 case JSCallMode::CALL_WITH_ARGV: 166 case JSCallMode::DEPRECATED_CALL_WITH_ARGV: 167 return false; 168 case JSCallMode::CALL_THIS_ARG0: 169 case JSCallMode::CALL_THIS_ARG1: 170 case JSCallMode::CALL_THIS_ARG2: 171 case JSCallMode::CALL_THIS_ARG3: 172 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV: 173 case JSCallMode::CALL_THIS_WITH_ARGV: 174 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 175 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 176 case JSCallMode::CALL_ENTRY: 177 case JSCallMode::CALL_FROM_AOT: 178 case JSCallMode::CALL_GETTER: 179 case JSCallMode::CALL_SETTER: 180 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN: 181 return true; 182 default: 183 UNREACHABLE(); 184 } 185 } 186 JSModeHaveNewTargetArg(JSCallMode mode)187bool AssemblerModule::JSModeHaveNewTargetArg(JSCallMode mode) 188 { 189 switch (mode) { 190 case JSCallMode::CALL_ARG0: 191 case JSCallMode::CALL_ARG1: 192 case JSCallMode::CALL_ARG2: 193 case JSCallMode::CALL_ARG3: 194 case JSCallMode::DEPRECATED_CALL_ARG0: 195 case JSCallMode::DEPRECATED_CALL_ARG1: 196 case JSCallMode::DEPRECATED_CALL_ARG2: 197 case JSCallMode::DEPRECATED_CALL_ARG3: 198 case JSCallMode::CALL_WITH_ARGV: 199 case JSCallMode::DEPRECATED_CALL_WITH_ARGV: 200 case JSCallMode::CALL_THIS_WITH_ARGV: 201 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV: 202 case JSCallMode::CALL_GETTER: 203 case JSCallMode::CALL_SETTER: 204 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN: 205 case JSCallMode::CALL_THIS_ARG0: 206 case JSCallMode::CALL_THIS_ARG1: 207 case JSCallMode::CALL_THIS_ARG2: 208 case JSCallMode::CALL_THIS_ARG3: 209 return false; 210 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 211 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 212 case JSCallMode::CALL_ENTRY: 213 case JSCallMode::CALL_FROM_AOT: 214 return true; 215 default: 216 UNREACHABLE(); 217 } 218 } 219 IsJumpToCallCommonEntry(JSCallMode mode)220bool AssemblerModule::IsJumpToCallCommonEntry(JSCallMode mode) 221 { 222 switch (mode) { 223 case JSCallMode::CALL_ARG0: 224 case JSCallMode::CALL_ARG1: 225 case JSCallMode::CALL_ARG2: 226 case JSCallMode::CALL_ARG3: 227 case JSCallMode::DEPRECATED_CALL_ARG0: 228 case JSCallMode::DEPRECATED_CALL_ARG1: 229 case JSCallMode::DEPRECATED_CALL_ARG2: 230 case JSCallMode::DEPRECATED_CALL_ARG3: 231 case JSCallMode::CALL_WITH_ARGV: 232 case JSCallMode::DEPRECATED_CALL_WITH_ARGV: 233 case JSCallMode::CALL_THIS_WITH_ARGV: 234 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV: 235 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 236 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 237 case JSCallMode::CALL_THIS_ARG0: 238 case JSCallMode::CALL_THIS_ARG1: 239 case JSCallMode::CALL_THIS_ARG2: 240 case JSCallMode::CALL_THIS_ARG3: 241 return true; 242 case JSCallMode::CALL_GETTER: 243 case JSCallMode::CALL_SETTER: 244 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN: 245 case JSCallMode::CALL_ENTRY: 246 case JSCallMode::CALL_GENERATOR: 247 case JSCallMode::CALL_FROM_AOT: 248 return false; 249 default: 250 UNREACHABLE(); 251 } 252 return false; 253 } 254 255 #define DECLARE_ASM_STUB_X64_GENERATE(name) \ 256 void name##Stub::GenerateX64(Assembler *assembler) \ 257 { \ 258 x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler); \ 259 x64::AssemblerStubsX64::name(assemblerX64); \ 260 assemblerX64->Align16(); \ 261 } 262 263 #define DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE(name) \ 264 void name##Stub::GenerateX64(Assembler *assembler) \ 265 { \ 266 x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler); \ 267 x64::OptimizedCall::name(assemblerX64); \ 268 assemblerX64->Align16(); \ 269 } 270 271 #define DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE(name) \ 272 void name##Stub::GenerateX64(Assembler *assembler) \ 273 { \ 274 x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler); \ 275 x64::AsmInterpreterCall::name(assemblerX64); \ 276 assemblerX64->Align16(); \ 277 } 278 279 280 #define DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE(name) \ 281 void name##Stub::GenerateAarch64(Assembler *assembler) \ 282 { \ 283 aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \ 284 aarch64::OptimizedCall::name(assemblerAarch64); \ 285 } 286 287 #define DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE(name) \ 288 void name##Stub::GenerateAarch64(Assembler *assembler) \ 289 { \ 290 aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \ 291 aarch64::AsmInterpreterCall::name(assemblerAarch64); \ 292 } 293 294 JS_CALL_TRAMPOLINE_LIST(DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE) 295 ASM_INTERPRETER_TRAMPOLINE_LIST(DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE) 296 JS_CALL_TRAMPOLINE_LIST(DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE) 297 ASM_INTERPRETER_TRAMPOLINE_LIST(DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE) 298 #undef DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE 299 #undef DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE 300 } // namespace panda::ecmascript::kunfu 301