1*795d594fSAndroid Build Coastguard Worker%def header(): 2*795d594fSAndroid Build Coastguard Worker/* 3*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project 4*795d594fSAndroid Build Coastguard Worker * 5*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 6*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 7*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 8*795d594fSAndroid Build Coastguard Worker * 9*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 10*795d594fSAndroid Build Coastguard Worker * 11*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 12*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 13*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 15*795d594fSAndroid Build Coastguard Worker * limitations under the License. 16*795d594fSAndroid Build Coastguard Worker */ 17*795d594fSAndroid Build Coastguard Worker 18*795d594fSAndroid Build Coastguard Worker/* 19*795d594fSAndroid Build Coastguard Worker * This is a #include, not a %include, because we want the C pre-processor 20*795d594fSAndroid Build Coastguard Worker * to expand the macros into assembler assignment statements. 21*795d594fSAndroid Build Coastguard Worker */ 22*795d594fSAndroid Build Coastguard Worker#include "asm_support.h" 23*795d594fSAndroid Build Coastguard Worker#include "arch/arm64/asm_support_arm64.S" 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker/** 26*795d594fSAndroid Build Coastguard Worker * ARM64 Runtime register usage conventions. 27*795d594fSAndroid Build Coastguard Worker * 28*795d594fSAndroid Build Coastguard Worker * r0 : w0 is 32-bit return register and x0 is 64-bit. 29*795d594fSAndroid Build Coastguard Worker * r0-r7 : Argument registers. 30*795d594fSAndroid Build Coastguard Worker * r8-r15 : Caller save registers (used as temporary registers). 31*795d594fSAndroid Build Coastguard Worker * r16-r17: Also known as ip0-ip1, respectively. Used as scratch registers by 32*795d594fSAndroid Build Coastguard Worker * the linker, by the trampolines and other stubs (the compiler uses 33*795d594fSAndroid Build Coastguard Worker * these as temporary registers). 34*795d594fSAndroid Build Coastguard Worker * r18 : Reserved for platform (SCS, shadow call stack) 35*795d594fSAndroid Build Coastguard Worker * r19 : Pointer to thread-local storage. 36*795d594fSAndroid Build Coastguard Worker * r20-r29: Callee save registers. 37*795d594fSAndroid Build Coastguard Worker * r30 : (lr) is reserved (the link register). 38*795d594fSAndroid Build Coastguard Worker * rsp : (sp) is reserved (the stack pointer). 39*795d594fSAndroid Build Coastguard Worker * rzr : (zr) is reserved (the zero register). 40*795d594fSAndroid Build Coastguard Worker * 41*795d594fSAndroid Build Coastguard Worker * Floating-point registers 42*795d594fSAndroid Build Coastguard Worker * v0-v31 43*795d594fSAndroid Build Coastguard Worker * 44*795d594fSAndroid Build Coastguard Worker * v0 : s0 is return register for singles (32-bit) and d0 for doubles (64-bit). 45*795d594fSAndroid Build Coastguard Worker * This is analogous to the C/C++ (hard-float) calling convention. 46*795d594fSAndroid Build Coastguard Worker * v0-v7 : Floating-point argument registers in both Dalvik and C/C++ conventions. 47*795d594fSAndroid Build Coastguard Worker * Also used as temporary and codegen scratch registers. 48*795d594fSAndroid Build Coastguard Worker * 49*795d594fSAndroid Build Coastguard Worker * v0-v7 and v16-v31 : Caller save registers (used as temporary registers). 50*795d594fSAndroid Build Coastguard Worker * v8-v15 : bottom 64-bits preserved across C calls (d8-d15 are preserved). 51*795d594fSAndroid Build Coastguard Worker * 52*795d594fSAndroid Build Coastguard Worker * v16-v31: Used as codegen temp/scratch. 53*795d594fSAndroid Build Coastguard Worker * v8-v15 : Can be used for promotion. 54*795d594fSAndroid Build Coastguard Worker * 55*795d594fSAndroid Build Coastguard Worker * Must maintain 16-byte stack alignment. 56*795d594fSAndroid Build Coastguard Worker * 57*795d594fSAndroid Build Coastguard Worker * Nterp notes: 58*795d594fSAndroid Build Coastguard Worker * 59*795d594fSAndroid Build Coastguard Worker * The following registers have fixed assignments: 60*795d594fSAndroid Build Coastguard Worker * 61*795d594fSAndroid Build Coastguard Worker * reg nick purpose 62*795d594fSAndroid Build Coastguard Worker * x19 xSELF self (Thread) pointer 63*795d594fSAndroid Build Coastguard Worker * x20 wMR marking register 64*795d594fSAndroid Build Coastguard Worker * x21 xSUSPEND suspend check register 65*795d594fSAndroid Build Coastguard Worker * x29 xFP interpreted frame pointer, used for accessing locals and args 66*795d594fSAndroid Build Coastguard Worker * x22 xPC interpreted program counter, used for fetching instructions 67*795d594fSAndroid Build Coastguard Worker * x23 xINST first 16-bit code unit of current instruction 68*795d594fSAndroid Build Coastguard Worker * x24 xIBASE interpreted instruction base pointer, used for computed goto 69*795d594fSAndroid Build Coastguard Worker * x25 xREFS base of object references of dex registers. 70*795d594fSAndroid Build Coastguard Worker * x16 ip scratch reg 71*795d594fSAndroid Build Coastguard Worker * x17 ip2 scratch reg (used by macros) 72*795d594fSAndroid Build Coastguard Worker * 73*795d594fSAndroid Build Coastguard Worker * Macros are provided for common operations. They MUST NOT alter unspecified registers or 74*795d594fSAndroid Build Coastguard Worker * condition codes. 75*795d594fSAndroid Build Coastguard Worker*/ 76*795d594fSAndroid Build Coastguard Worker 77*795d594fSAndroid Build Coastguard Worker/* single-purpose registers, given names for clarity */ 78*795d594fSAndroid Build Coastguard Worker#define CFI_DEX 22 // DWARF register number of the register holding dex-pc (xPC). 79*795d594fSAndroid Build Coastguard Worker#define CFI_TMP 0 // DWARF register number of the first argument register (r0). 80*795d594fSAndroid Build Coastguard Worker#define xPC x22 81*795d594fSAndroid Build Coastguard Worker#define xINST x23 82*795d594fSAndroid Build Coastguard Worker#define wINST w23 83*795d594fSAndroid Build Coastguard Worker#define xIBASE x24 84*795d594fSAndroid Build Coastguard Worker#define xREFS x25 85*795d594fSAndroid Build Coastguard Worker#define CFI_REFS 25 86*795d594fSAndroid Build Coastguard Worker#define ip x16 87*795d594fSAndroid Build Coastguard Worker#define ip2 x17 88*795d594fSAndroid Build Coastguard Worker#define wip w16 89*795d594fSAndroid Build Coastguard Worker#define wip2 w17 90*795d594fSAndroid Build Coastguard Worker 91*795d594fSAndroid Build Coastguard Worker// To avoid putting ifdefs arond the use of wMR, make sure it's defined. 92*795d594fSAndroid Build Coastguard Worker// IsNterpSupported returns false for configurations that don't have wMR (typically CMS). 93*795d594fSAndroid Build Coastguard Worker#ifndef wMR 94*795d594fSAndroid Build Coastguard Worker#define wMR w20 95*795d594fSAndroid Build Coastguard Worker#endif 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker// Temporary registers while setting up a frame. 98*795d594fSAndroid Build Coastguard Worker#define xNEW_FP x26 99*795d594fSAndroid Build Coastguard Worker#define xNEW_REFS x27 100*795d594fSAndroid Build Coastguard Worker#define CFI_NEW_REFS 27 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker// +8 for the ArtMethod of the caller. 103*795d594fSAndroid Build Coastguard Worker#define OFFSET_TO_FIRST_ARGUMENT_IN_STACK (CALLEE_SAVES_SIZE + 8) 104*795d594fSAndroid Build Coastguard Worker 105*795d594fSAndroid Build Coastguard Worker/* 106*795d594fSAndroid Build Coastguard Worker * Fetch the next instruction from xPC into wINST. Does not advance xPC. 107*795d594fSAndroid Build Coastguard Worker */ 108*795d594fSAndroid Build Coastguard Worker.macro FETCH_INST 109*795d594fSAndroid Build Coastguard Worker ldrh wINST, [xPC] 110*795d594fSAndroid Build Coastguard Worker.endm 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker/* 113*795d594fSAndroid Build Coastguard Worker * Fetch the next instruction from the specified offset. Advances xPC 114*795d594fSAndroid Build Coastguard Worker * to point to the next instruction. "count" is in 16-bit code units. 115*795d594fSAndroid Build Coastguard Worker * 116*795d594fSAndroid Build Coastguard Worker * Because of the limited size of immediate constants on ARM, this is only 117*795d594fSAndroid Build Coastguard Worker * suitable for small forward movements (i.e. don't try to implement "goto" 118*795d594fSAndroid Build Coastguard Worker * with this). 119*795d594fSAndroid Build Coastguard Worker * 120*795d594fSAndroid Build Coastguard Worker * This must come AFTER anything that can throw an exception, or the 121*795d594fSAndroid Build Coastguard Worker * exception catch may miss. (This also implies that it must come after 122*795d594fSAndroid Build Coastguard Worker * EXPORT_PC.) 123*795d594fSAndroid Build Coastguard Worker */ 124*795d594fSAndroid Build Coastguard Worker.macro FETCH_ADVANCE_INST count 125*795d594fSAndroid Build Coastguard Worker ldrh wINST, [xPC, #((\count)*2)]! 126*795d594fSAndroid Build Coastguard Worker.endm 127*795d594fSAndroid Build Coastguard Worker 128*795d594fSAndroid Build Coastguard Worker/* 129*795d594fSAndroid Build Coastguard Worker * Similar to FETCH_ADVANCE_INST, but does not update xPC. Used to load 130*795d594fSAndroid Build Coastguard Worker * xINST ahead of possible exception point. Be sure to manually advance xPC 131*795d594fSAndroid Build Coastguard Worker * later. 132*795d594fSAndroid Build Coastguard Worker */ 133*795d594fSAndroid Build Coastguard Worker.macro PREFETCH_INST count 134*795d594fSAndroid Build Coastguard Worker ldrh wINST, [xPC, #((\count)*2)] 135*795d594fSAndroid Build Coastguard Worker.endm 136*795d594fSAndroid Build Coastguard Worker 137*795d594fSAndroid Build Coastguard Worker/* Advance xPC by some number of code units. */ 138*795d594fSAndroid Build Coastguard Worker.macro ADVANCE count 139*795d594fSAndroid Build Coastguard Worker add xPC, xPC, #((\count)*2) 140*795d594fSAndroid Build Coastguard Worker.endm 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker/* 143*795d594fSAndroid Build Coastguard Worker * Fetch a half-word code unit from an offset past the current PC. The 144*795d594fSAndroid Build Coastguard Worker * "count" value is in 16-bit code units. Does not advance xPC. 145*795d594fSAndroid Build Coastguard Worker * 146*795d594fSAndroid Build Coastguard Worker * The "_S" variant works the same but treats the value as signed. 147*795d594fSAndroid Build Coastguard Worker */ 148*795d594fSAndroid Build Coastguard Worker.macro FETCH reg, count 149*795d594fSAndroid Build Coastguard Worker ldrh \reg, [xPC, #((\count)*2)] 150*795d594fSAndroid Build Coastguard Worker.endm 151*795d594fSAndroid Build Coastguard Worker 152*795d594fSAndroid Build Coastguard Worker.macro FETCH_S reg, count 153*795d594fSAndroid Build Coastguard Worker ldrsh \reg, [xPC, #((\count)*2)] 154*795d594fSAndroid Build Coastguard Worker.endm 155*795d594fSAndroid Build Coastguard Worker 156*795d594fSAndroid Build Coastguard Worker/* 157*795d594fSAndroid Build Coastguard Worker * Fetch one byte from an offset past the current PC. Pass in the same 158*795d594fSAndroid Build Coastguard Worker * "count" as you would for FETCH, and an additional 0/1 indicating which 159*795d594fSAndroid Build Coastguard Worker * byte of the halfword you want (lo/hi). 160*795d594fSAndroid Build Coastguard Worker */ 161*795d594fSAndroid Build Coastguard Worker.macro FETCH_B reg, count, byte 162*795d594fSAndroid Build Coastguard Worker ldrb \reg, [xPC, #((\count)*2+(\byte))] 163*795d594fSAndroid Build Coastguard Worker.endm 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker/* 166*795d594fSAndroid Build Coastguard Worker * Put the instruction's opcode field into the specified register. 167*795d594fSAndroid Build Coastguard Worker */ 168*795d594fSAndroid Build Coastguard Worker.macro GET_INST_OPCODE reg 169*795d594fSAndroid Build Coastguard Worker and \reg, xINST, #255 170*795d594fSAndroid Build Coastguard Worker.endm 171*795d594fSAndroid Build Coastguard Worker 172*795d594fSAndroid Build Coastguard Worker/* 173*795d594fSAndroid Build Coastguard Worker * Begin executing the opcode in _reg. Clobbers reg 174*795d594fSAndroid Build Coastguard Worker */ 175*795d594fSAndroid Build Coastguard Worker 176*795d594fSAndroid Build Coastguard Worker.macro GOTO_OPCODE reg 177*795d594fSAndroid Build Coastguard Worker add \reg, xIBASE, \reg, lsl #${handler_size_bits} 178*795d594fSAndroid Build Coastguard Worker br \reg 179*795d594fSAndroid Build Coastguard Worker.endm 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker/* 182*795d594fSAndroid Build Coastguard Worker * Get/set the 32-bit value from a Dalvik register. 183*795d594fSAndroid Build Coastguard Worker */ 184*795d594fSAndroid Build Coastguard Worker.macro GET_VREG reg, vreg 185*795d594fSAndroid Build Coastguard Worker ldr \reg, [xFP, \vreg, uxtw #2] 186*795d594fSAndroid Build Coastguard Worker.endm 187*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_OBJECT reg, vreg 188*795d594fSAndroid Build Coastguard Worker ldr \reg, [xREFS, \vreg, uxtw #2] 189*795d594fSAndroid Build Coastguard Worker.endm 190*795d594fSAndroid Build Coastguard Worker.macro SET_VREG reg, vreg 191*795d594fSAndroid Build Coastguard Worker str \reg, [xFP, \vreg, uxtw #2] 192*795d594fSAndroid Build Coastguard Worker str wzr, [xREFS, \vreg, uxtw #2] 193*795d594fSAndroid Build Coastguard Worker.endm 194*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_OBJECT reg, vreg 195*795d594fSAndroid Build Coastguard Worker str \reg, [xFP, \vreg, uxtw #2] 196*795d594fSAndroid Build Coastguard Worker str \reg, [xREFS, \vreg, uxtw #2] 197*795d594fSAndroid Build Coastguard Worker.endm 198*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_FLOAT reg, vreg 199*795d594fSAndroid Build Coastguard Worker str \reg, [xFP, \vreg, uxtw #2] 200*795d594fSAndroid Build Coastguard Worker str wzr, [xREFS, \vreg, uxtw #2] 201*795d594fSAndroid Build Coastguard Worker.endm 202*795d594fSAndroid Build Coastguard Worker 203*795d594fSAndroid Build Coastguard Worker/* 204*795d594fSAndroid Build Coastguard Worker * Get/set the 64-bit value from a Dalvik register. 205*795d594fSAndroid Build Coastguard Worker */ 206*795d594fSAndroid Build Coastguard Worker.macro LOAD_SCALED_VREG_MASK scaled_mask_reg, unscaled_mask 207*795d594fSAndroid Build Coastguard Worker mov \scaled_mask_reg, \unscaled_mask << 2 208*795d594fSAndroid Build Coastguard Worker.endm 209*795d594fSAndroid Build Coastguard Worker.macro EXTRACT_SCALED_VREG scaled_vreg, scaled_mask_reg, src_reg, lsb 210*795d594fSAndroid Build Coastguard Worker .if \lsb < 2 211*795d594fSAndroid Build Coastguard Worker and \scaled_vreg, \scaled_mask_reg, \src_reg, lsl #(2 - \lsb) 212*795d594fSAndroid Build Coastguard Worker .else 213*795d594fSAndroid Build Coastguard Worker and \scaled_vreg, \scaled_mask_reg, \src_reg, lsr #(\lsb - 2) 214*795d594fSAndroid Build Coastguard Worker .endif 215*795d594fSAndroid Build Coastguard Worker.endm 216*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_WIDE_PRESCALED reg, scaled_vreg 217*795d594fSAndroid Build Coastguard Worker ldr \reg, [xFP, \scaled_vreg, uxtw] 218*795d594fSAndroid Build Coastguard Worker.endm 219*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_WIDE reg, vreg 220*795d594fSAndroid Build Coastguard Worker lsl wip2, \vreg, #2 221*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE_PRESCALED \reg, wip2 222*795d594fSAndroid Build Coastguard Worker.endm 223*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_WIDE_PRESCALED reg, scaled_vreg 224*795d594fSAndroid Build Coastguard Worker str \reg, [xFP, \scaled_vreg, uxtw] 225*795d594fSAndroid Build Coastguard Worker str xzr, [xREFS, \scaled_vreg, uxtw] 226*795d594fSAndroid Build Coastguard Worker.endm 227*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_WIDE reg, vreg 228*795d594fSAndroid Build Coastguard Worker lsl wip2, \vreg, #2 229*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE_PRESCALED \reg, wip2 230*795d594fSAndroid Build Coastguard Worker.endm 231*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_DOUBLE_PRESCALED reg, scaled_vreg 232*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE_PRESCALED \reg, \scaled_vreg 233*795d594fSAndroid Build Coastguard Worker.endm 234*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_DOUBLE reg, vreg 235*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE \reg, \vreg 236*795d594fSAndroid Build Coastguard Worker.endm 237*795d594fSAndroid Build Coastguard Worker.macro SET_VREG_DOUBLE reg, vreg 238*795d594fSAndroid Build Coastguard Worker SET_VREG_WIDE \reg, \vreg 239*795d594fSAndroid Build Coastguard Worker.endm 240*795d594fSAndroid Build Coastguard Worker 241*795d594fSAndroid Build Coastguard Worker/* 242*795d594fSAndroid Build Coastguard Worker * Get the 32-bit value from a Dalvik register and sign-extend to 64-bit. 243*795d594fSAndroid Build Coastguard Worker * Used to avoid an extra instruction in int-to-long. 244*795d594fSAndroid Build Coastguard Worker */ 245*795d594fSAndroid Build Coastguard Worker.macro GET_VREG_S reg, vreg 246*795d594fSAndroid Build Coastguard Worker ldrsw \reg, [xFP, \vreg, uxtw #2] 247*795d594fSAndroid Build Coastguard Worker.endm 248*795d594fSAndroid Build Coastguard Worker 249*795d594fSAndroid Build Coastguard Worker// An assembly entry for nterp. 250*795d594fSAndroid Build Coastguard Worker.macro OAT_ENTRY name 251*795d594fSAndroid Build Coastguard Worker .type \name, #function 252*795d594fSAndroid Build Coastguard Worker .hidden \name 253*795d594fSAndroid Build Coastguard Worker .global \name 254*795d594fSAndroid Build Coastguard Worker .balign 16 255*795d594fSAndroid Build Coastguard Worker\name: 256*795d594fSAndroid Build Coastguard Worker.endm 257*795d594fSAndroid Build Coastguard Worker 258*795d594fSAndroid Build Coastguard Worker.macro SIZE name 259*795d594fSAndroid Build Coastguard Worker .size \name, .-\name 260*795d594fSAndroid Build Coastguard Worker.endm 261*795d594fSAndroid Build Coastguard Worker 262*795d594fSAndroid Build Coastguard Worker.macro NAME_START name 263*795d594fSAndroid Build Coastguard Worker .type \name, #function 264*795d594fSAndroid Build Coastguard Worker .hidden \name // Hide this as a global symbol, so we do not incur plt calls. 265*795d594fSAndroid Build Coastguard Worker .global \name 266*795d594fSAndroid Build Coastguard Worker /* Cache alignment for function entry */ 267*795d594fSAndroid Build Coastguard Worker .balign 16 268*795d594fSAndroid Build Coastguard Worker\name: 269*795d594fSAndroid Build Coastguard Worker.endm 270*795d594fSAndroid Build Coastguard Worker 271*795d594fSAndroid Build Coastguard Worker.macro NAME_END name 272*795d594fSAndroid Build Coastguard Worker SIZE \name 273*795d594fSAndroid Build Coastguard Worker.endm 274*795d594fSAndroid Build Coastguard Worker 275*795d594fSAndroid Build Coastguard Worker// Macro for defining entrypoints into runtime. We don't need to save registers 276*795d594fSAndroid Build Coastguard Worker// (we're not holding references there), but there is no 277*795d594fSAndroid Build Coastguard Worker// kDontSave runtime method. So just use the kSaveRefsOnly runtime method. 278*795d594fSAndroid Build Coastguard Worker.macro NTERP_TRAMPOLINE name, helper 279*795d594fSAndroid Build Coastguard WorkerENTRY \name 280*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME 281*795d594fSAndroid Build Coastguard Worker bl \helper 282*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 283*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 284*795d594fSAndroid Build Coastguard Worker ldr xIP0, [xSELF, # THREAD_EXCEPTION_OFFSET] // Get exception field. 285*795d594fSAndroid Build Coastguard Worker cbnz xIP0, nterp_deliver_pending_exception 286*795d594fSAndroid Build Coastguard Worker ret 287*795d594fSAndroid Build Coastguard WorkerEND \name 288*795d594fSAndroid Build Coastguard Worker.endm 289*795d594fSAndroid Build Coastguard Worker 290*795d594fSAndroid Build Coastguard Worker.macro CLEAR_STATIC_VOLATILE_MARKER reg 291*795d594fSAndroid Build Coastguard Worker and \reg, \reg, #-2 292*795d594fSAndroid Build Coastguard Worker.endm 293*795d594fSAndroid Build Coastguard Worker 294*795d594fSAndroid Build Coastguard Worker.macro CLEAR_INSTANCE_VOLATILE_MARKER reg 295*795d594fSAndroid Build Coastguard Worker neg \reg, \reg 296*795d594fSAndroid Build Coastguard Worker.endm 297*795d594fSAndroid Build Coastguard Worker 298*795d594fSAndroid Build Coastguard Worker.macro EXPORT_PC 299*795d594fSAndroid Build Coastguard Worker str xPC, [xREFS, #-16] 300*795d594fSAndroid Build Coastguard Worker.endm 301*795d594fSAndroid Build Coastguard Worker 302*795d594fSAndroid Build Coastguard Worker.macro BRANCH 303*795d594fSAndroid Build Coastguard Worker add xPC, xPC, wINST, sxtw #1 // update xPC 304*795d594fSAndroid Build Coastguard Worker // Update method counter and do a suspend check if the branch is negative or zero. 305*795d594fSAndroid Build Coastguard Worker cmp wINST, #0 306*795d594fSAndroid Build Coastguard Worker b.le 2f 307*795d594fSAndroid Build Coastguard Worker1: 308*795d594fSAndroid Build Coastguard Worker FETCH wINST, 0 // load wINST 309*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from wINST 310*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 311*795d594fSAndroid Build Coastguard Worker2: 312*795d594fSAndroid Build Coastguard Worker ldr x0, [sp] 313*795d594fSAndroid Build Coastguard Worker ldrh w2, [x0, #ART_METHOD_HOTNESS_COUNT_OFFSET] 314*795d594fSAndroid Build Coastguard Worker#if (NTERP_HOTNESS_VALUE != 0) 315*795d594fSAndroid Build Coastguard Worker#error Expected 0 for hotness value 316*795d594fSAndroid Build Coastguard Worker#endif 317*795d594fSAndroid Build Coastguard Worker // If the counter is at zero, handle this in the runtime. 318*795d594fSAndroid Build Coastguard Worker cbz w2, NterpHandleHotnessOverflow 319*795d594fSAndroid Build Coastguard Worker add x2, x2, #-1 320*795d594fSAndroid Build Coastguard Worker strh w2, [x0, #ART_METHOD_HOTNESS_COUNT_OFFSET] 321*795d594fSAndroid Build Coastguard Worker DO_SUSPEND_CHECK continue_label=1b 322*795d594fSAndroid Build Coastguard Worker b 1b 323*795d594fSAndroid Build Coastguard Worker.endm 324*795d594fSAndroid Build Coastguard Worker 325*795d594fSAndroid Build Coastguard Worker// Uses x12, x13, and x14 as temporaries. 326*795d594fSAndroid Build Coastguard Worker.macro FETCH_CODE_ITEM_INFO code_item, registers, outs, ins, load_ins 327*795d594fSAndroid Build Coastguard Worker // Fetch dex register size. 328*795d594fSAndroid Build Coastguard Worker ldrh \registers, [\code_item, #CODE_ITEM_REGISTERS_SIZE_OFFSET] 329*795d594fSAndroid Build Coastguard Worker // Fetch outs size. 330*795d594fSAndroid Build Coastguard Worker ldrh \outs, [\code_item, #CODE_ITEM_OUTS_SIZE_OFFSET] 331*795d594fSAndroid Build Coastguard Worker .if \load_ins 332*795d594fSAndroid Build Coastguard Worker ldrh \ins, [\code_item, #CODE_ITEM_INS_SIZE_OFFSET] 333*795d594fSAndroid Build Coastguard Worker .endif 334*795d594fSAndroid Build Coastguard Worker add \code_item, \code_item, #CODE_ITEM_INSNS_OFFSET 335*795d594fSAndroid Build Coastguard Worker.endm 336*795d594fSAndroid Build Coastguard Worker 337*795d594fSAndroid Build Coastguard Worker.macro TEST_IF_MARKING label 338*795d594fSAndroid Build Coastguard Worker cbnz wMR, \label 339*795d594fSAndroid Build Coastguard Worker.endm 340*795d594fSAndroid Build Coastguard Worker 341*795d594fSAndroid Build Coastguard Worker// Setup the stack to start executing the method. Expects: 342*795d594fSAndroid Build Coastguard Worker// - x0 to contain the ArtMethod 343*795d594fSAndroid Build Coastguard Worker// 344*795d594fSAndroid Build Coastguard Worker// Outputs 345*795d594fSAndroid Build Coastguard Worker// - ip contains the dex registers size 346*795d594fSAndroid Build Coastguard Worker// - x28 contains the old stack pointer. 347*795d594fSAndroid Build Coastguard Worker// - \code_item is replaced with a pointer to the instructions 348*795d594fSAndroid Build Coastguard Worker// - if load_ins is 1, w15 contains the ins 349*795d594fSAndroid Build Coastguard Worker// 350*795d594fSAndroid Build Coastguard Worker// Uses ip, ip2, x12, x13, x14 as temporaries. 351*795d594fSAndroid Build Coastguard Worker.macro SETUP_STACK_FRAME code_item, refs, fp, cfi_refs, load_ins 352*795d594fSAndroid Build Coastguard Worker FETCH_CODE_ITEM_INFO \code_item, wip, wip2, w15, \load_ins 353*795d594fSAndroid Build Coastguard Worker 354*795d594fSAndroid Build Coastguard Worker // Compute required frame size: ((2 * ip) + ip2) * 4 + 24 355*795d594fSAndroid Build Coastguard Worker // 24 is for saving the previous frame, pc, and method being executed. 356*795d594fSAndroid Build Coastguard Worker add x14, ip, ip 357*795d594fSAndroid Build Coastguard Worker add x14, x14, ip2 358*795d594fSAndroid Build Coastguard Worker lsl x14, x14, #2 359*795d594fSAndroid Build Coastguard Worker add x14, x14, #24 360*795d594fSAndroid Build Coastguard Worker 361*795d594fSAndroid Build Coastguard Worker // Compute new stack pointer in x14 362*795d594fSAndroid Build Coastguard Worker sub x14, sp, x14 363*795d594fSAndroid Build Coastguard Worker // Alignment 364*795d594fSAndroid Build Coastguard Worker and x14, x14, #-16 365*795d594fSAndroid Build Coastguard Worker 366*795d594fSAndroid Build Coastguard Worker // Set reference and dex registers, align to pointer size for previous frame and dex pc. 367*795d594fSAndroid Build Coastguard Worker add \refs, x14, ip2, lsl #2 368*795d594fSAndroid Build Coastguard Worker add \refs, \refs, 28 369*795d594fSAndroid Build Coastguard Worker and \refs, \refs, #(-__SIZEOF_POINTER__) 370*795d594fSAndroid Build Coastguard Worker add \fp, \refs, ip, lsl #2 371*795d594fSAndroid Build Coastguard Worker 372*795d594fSAndroid Build Coastguard Worker // Now setup the stack pointer. 373*795d594fSAndroid Build Coastguard Worker mov x28, sp 374*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa_register x28 375*795d594fSAndroid Build Coastguard Worker mov sp, x14 376*795d594fSAndroid Build Coastguard Worker str x28, [\refs, #-8] 377*795d594fSAndroid Build Coastguard Worker CFI_DEF_CFA_BREG_PLUS_UCONST \cfi_refs, -8, CALLEE_SAVES_SIZE 378*795d594fSAndroid Build Coastguard Worker 379*795d594fSAndroid Build Coastguard Worker // Put nulls in reference frame. 380*795d594fSAndroid Build Coastguard Worker cbz ip, 2f 381*795d594fSAndroid Build Coastguard Worker mov ip2, \refs 382*795d594fSAndroid Build Coastguard Worker1: 383*795d594fSAndroid Build Coastguard Worker str xzr, [ip2], #8 // May clear vreg[0]. 384*795d594fSAndroid Build Coastguard Worker cmp ip2, \fp 385*795d594fSAndroid Build Coastguard Worker b.lo 1b 386*795d594fSAndroid Build Coastguard Worker2: 387*795d594fSAndroid Build Coastguard Worker // Save the ArtMethod. 388*795d594fSAndroid Build Coastguard Worker str x0, [sp] 389*795d594fSAndroid Build Coastguard Worker.endm 390*795d594fSAndroid Build Coastguard Worker 391*795d594fSAndroid Build Coastguard Worker// Increase method hotness and do suspend check before starting executing the method. 392*795d594fSAndroid Build Coastguard Worker.macro START_EXECUTING_INSTRUCTIONS 393*795d594fSAndroid Build Coastguard Worker ldr x0, [sp] 394*795d594fSAndroid Build Coastguard Worker ldrh w2, [x0, #ART_METHOD_HOTNESS_COUNT_OFFSET] 395*795d594fSAndroid Build Coastguard Worker#if (NTERP_HOTNESS_VALUE != 0) 396*795d594fSAndroid Build Coastguard Worker#error Expected 0 for hotness value 397*795d594fSAndroid Build Coastguard Worker#endif 398*795d594fSAndroid Build Coastguard Worker // If the counter is at zero, handle this in the runtime. 399*795d594fSAndroid Build Coastguard Worker cbz w2, 3f 400*795d594fSAndroid Build Coastguard Worker add x2, x2, #-1 401*795d594fSAndroid Build Coastguard Worker strh w2, [x0, #ART_METHOD_HOTNESS_COUNT_OFFSET] 402*795d594fSAndroid Build Coastguard Worker1: 403*795d594fSAndroid Build Coastguard Worker DO_SUSPEND_CHECK continue_label=2f 404*795d594fSAndroid Build Coastguard Worker2: 405*795d594fSAndroid Build Coastguard Worker FETCH_INST 406*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 407*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 408*795d594fSAndroid Build Coastguard Worker3: 409*795d594fSAndroid Build Coastguard Worker CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot=4f, if_not_hot=1b 410*795d594fSAndroid Build Coastguard Worker4: 411*795d594fSAndroid Build Coastguard Worker mov x1, xzr 412*795d594fSAndroid Build Coastguard Worker mov x2, xFP 413*795d594fSAndroid Build Coastguard Worker bl nterp_hot_method 414*795d594fSAndroid Build Coastguard Worker b 2b 415*795d594fSAndroid Build Coastguard Worker.endm 416*795d594fSAndroid Build Coastguard Worker 417*795d594fSAndroid Build Coastguard Worker.macro SPILL_ALL_CALLEE_SAVES 418*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME CALLEE_SAVES_SIZE 419*795d594fSAndroid Build Coastguard Worker // Note: we technically don't need to save x19 and x20, 420*795d594fSAndroid Build Coastguard Worker // but the runtime will expect those values to be there when unwinding 421*795d594fSAndroid Build Coastguard Worker // (see Arm64Context::DoLongJump checking for the thread register). 422*795d594fSAndroid Build Coastguard Worker SAVE_ALL_CALLEE_SAVES 0 423*795d594fSAndroid Build Coastguard Worker.endm 424*795d594fSAndroid Build Coastguard Worker 425*795d594fSAndroid Build Coastguard Worker.macro RESTORE_ALL_CALLEE_SAVES 426*795d594fSAndroid Build Coastguard Worker // FP callee-saves 427*795d594fSAndroid Build Coastguard Worker ldp d8, d9, [sp, #0] 428*795d594fSAndroid Build Coastguard Worker ldp d10, d11, [sp, #16] 429*795d594fSAndroid Build Coastguard Worker ldp d12, d13, [sp, #32] 430*795d594fSAndroid Build Coastguard Worker ldp d14, d15, [sp, #48] 431*795d594fSAndroid Build Coastguard Worker 432*795d594fSAndroid Build Coastguard Worker // GP callee-saves. 433*795d594fSAndroid Build Coastguard Worker // No need to restore x19 (it's always the thread), and 434*795d594fSAndroid Build Coastguard Worker // don't restore x20 (the marking register) as it may have been updated, 435*795d594fSAndroid Build Coastguard Worker // don't restore x21 (the suspend check register) as it may have been updated. 436*795d594fSAndroid Build Coastguard Worker RESTORE_REG x22, 88 437*795d594fSAndroid Build Coastguard Worker RESTORE_TWO_REGS x23, x24, 96 438*795d594fSAndroid Build Coastguard Worker RESTORE_TWO_REGS x25, x26, 112 439*795d594fSAndroid Build Coastguard Worker RESTORE_TWO_REGS x27, x28, 128 440*795d594fSAndroid Build Coastguard Worker RESTORE_TWO_REGS x29, lr, 144 441*795d594fSAndroid Build Coastguard Worker 442*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME CALLEE_SAVES_SIZE 443*795d594fSAndroid Build Coastguard Worker.endm 444*795d594fSAndroid Build Coastguard Worker 445*795d594fSAndroid Build Coastguard Worker.macro SPILL_ALL_ARGUMENTS 446*795d594fSAndroid Build Coastguard Worker stp x0, x1, [sp, #-128]! 447*795d594fSAndroid Build Coastguard Worker stp x2, x3, [sp, #16] 448*795d594fSAndroid Build Coastguard Worker stp x4, x5, [sp, #32] 449*795d594fSAndroid Build Coastguard Worker stp x6, x7, [sp, #48] 450*795d594fSAndroid Build Coastguard Worker stp d0, d1, [sp, #64] 451*795d594fSAndroid Build Coastguard Worker stp d2, d3, [sp, #80] 452*795d594fSAndroid Build Coastguard Worker stp d4, d5, [sp, #96] 453*795d594fSAndroid Build Coastguard Worker stp d6, d7, [sp, #112] 454*795d594fSAndroid Build Coastguard Worker.endm 455*795d594fSAndroid Build Coastguard Worker 456*795d594fSAndroid Build Coastguard Worker.macro RESTORE_ALL_ARGUMENTS 457*795d594fSAndroid Build Coastguard Worker ldp x2, x3, [sp, #16] 458*795d594fSAndroid Build Coastguard Worker ldp x4, x5, [sp, #32] 459*795d594fSAndroid Build Coastguard Worker ldp x6, x7, [sp, #48] 460*795d594fSAndroid Build Coastguard Worker ldp d0, d1, [sp, #64] 461*795d594fSAndroid Build Coastguard Worker ldp d2, d3, [sp, #80] 462*795d594fSAndroid Build Coastguard Worker ldp d4, d5, [sp, #96] 463*795d594fSAndroid Build Coastguard Worker ldp d6, d7, [sp, #112] 464*795d594fSAndroid Build Coastguard Worker ldp x0, x1, [sp], #128 465*795d594fSAndroid Build Coastguard Worker.endm 466*795d594fSAndroid Build Coastguard Worker 467*795d594fSAndroid Build Coastguard Worker// Helper to setup the stack after doing a nterp to nterp call. This will setup: 468*795d594fSAndroid Build Coastguard Worker// - xNEW_FP: the new pointer to dex registers 469*795d594fSAndroid Build Coastguard Worker// - xNEW_REFS: the new pointer to references 470*795d594fSAndroid Build Coastguard Worker// - xPC: the new PC pointer to execute 471*795d594fSAndroid Build Coastguard Worker// - x2: value in instruction to decode the number of arguments. 472*795d594fSAndroid Build Coastguard Worker// - x3: first dex register 473*795d594fSAndroid Build Coastguard Worker// - x4: top of dex register array 474*795d594fSAndroid Build Coastguard Worker// 475*795d594fSAndroid Build Coastguard Worker// The method expects: 476*795d594fSAndroid Build Coastguard Worker// - x0 to contain the ArtMethod 477*795d594fSAndroid Build Coastguard Worker// - x8 to contain the code item 478*795d594fSAndroid Build Coastguard Worker.macro SETUP_STACK_FOR_INVOKE 479*795d594fSAndroid Build Coastguard Worker // We do the same stack overflow check as the compiler. See CanMethodUseNterp 480*795d594fSAndroid Build Coastguard Worker // in how we limit the maximum nterp frame size. 481*795d594fSAndroid Build Coastguard Worker sub x16, sp, #STACK_OVERFLOW_RESERVED_BYTES 482*795d594fSAndroid Build Coastguard Worker ldr wzr, [x16] 483*795d594fSAndroid Build Coastguard Worker 484*795d594fSAndroid Build Coastguard Worker // Spill all callee saves to have a consistent stack frame whether we 485*795d594fSAndroid Build Coastguard Worker // are called by compiled code or nterp. 486*795d594fSAndroid Build Coastguard Worker SPILL_ALL_CALLEE_SAVES 487*795d594fSAndroid Build Coastguard Worker 488*795d594fSAndroid Build Coastguard Worker // Setup the frame. 489*795d594fSAndroid Build Coastguard Worker SETUP_STACK_FRAME x8, xNEW_REFS, xNEW_FP, CFI_NEW_REFS, load_ins=0 490*795d594fSAndroid Build Coastguard Worker // Make x4 point to the top of the dex register array. 491*795d594fSAndroid Build Coastguard Worker add x4, xNEW_FP, ip, uxtx #2 492*795d594fSAndroid Build Coastguard Worker 493*795d594fSAndroid Build Coastguard Worker // Fetch instruction information before replacing xPC. 494*795d594fSAndroid Build Coastguard Worker // TODO: move this down to the method that uses it, fetching it directly from wINST. 495*795d594fSAndroid Build Coastguard Worker FETCH_B w2, 0, 1 496*795d594fSAndroid Build Coastguard Worker // TODO: we could avoid this as instance invokes already fetch it. 497*795d594fSAndroid Build Coastguard Worker FETCH w3, 2 498*795d594fSAndroid Build Coastguard Worker 499*795d594fSAndroid Build Coastguard Worker // Set the dex pc pointer. 500*795d594fSAndroid Build Coastguard Worker mov xPC, x8 501*795d594fSAndroid Build Coastguard Worker CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0) 502*795d594fSAndroid Build Coastguard Worker.endm 503*795d594fSAndroid Build Coastguard Worker 504*795d594fSAndroid Build Coastguard Worker// Setup arguments based on a non-range nterp to nterp call, and start executing 505*795d594fSAndroid Build Coastguard Worker// the method. We expect: 506*795d594fSAndroid Build Coastguard Worker// - xNEW_FP: the new pointer to dex registers 507*795d594fSAndroid Build Coastguard Worker// - xNEW_REFS: the new pointer to references 508*795d594fSAndroid Build Coastguard Worker// - xPC: the new PC pointer to execute 509*795d594fSAndroid Build Coastguard Worker// - x2: number of arguments (bits 4-7), 5th argument if any (bits 0-3) 510*795d594fSAndroid Build Coastguard Worker// - x3: first dex register 511*795d594fSAndroid Build Coastguard Worker// - x4: top of dex register array 512*795d594fSAndroid Build Coastguard Worker// - x1: receiver if non-static. 513*795d594fSAndroid Build Coastguard Worker.macro SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0 514*795d594fSAndroid Build Coastguard Worker // /* op vA, vB, {vC...vG} */ 515*795d594fSAndroid Build Coastguard Worker asr ip2, x2, #4 516*795d594fSAndroid Build Coastguard Worker cbz ip2, 6f 517*795d594fSAndroid Build Coastguard Worker mov ip, #-4 518*795d594fSAndroid Build Coastguard Worker cmp ip2, #2 519*795d594fSAndroid Build Coastguard Worker b.lt 1f 520*795d594fSAndroid Build Coastguard Worker b.eq 2f 521*795d594fSAndroid Build Coastguard Worker cmp ip2, #4 522*795d594fSAndroid Build Coastguard Worker b.lt 3f 523*795d594fSAndroid Build Coastguard Worker b.eq 4f 524*795d594fSAndroid Build Coastguard Worker 525*795d594fSAndroid Build Coastguard Worker // We use a decrementing ip to store references relative 526*795d594fSAndroid Build Coastguard Worker // to xNEW_FP and dex registers relative to x4 527*795d594fSAndroid Build Coastguard Worker // 528*795d594fSAndroid Build Coastguard Worker // TODO: We could set up ip as the number of registers (this can be an additional output from 529*795d594fSAndroid Build Coastguard Worker // SETUP_STACK_FOR_INVOKE) and then just decrement it by one before copying each arg. 530*795d594fSAndroid Build Coastguard Worker // Maybe even introduce macros NEW_VREG_ADDRESS/NEW_VREG_REF_ADDRESS. 531*795d594fSAndroid Build Coastguard Worker5: 532*795d594fSAndroid Build Coastguard Worker and x2, x2, #15 533*795d594fSAndroid Build Coastguard Worker GET_VREG_OBJECT w5, w2 534*795d594fSAndroid Build Coastguard Worker str w5, [xNEW_FP, ip] 535*795d594fSAndroid Build Coastguard Worker GET_VREG w5, w2 536*795d594fSAndroid Build Coastguard Worker str w5, [x4, ip] 537*795d594fSAndroid Build Coastguard Worker sub ip, ip, #4 538*795d594fSAndroid Build Coastguard Worker4: 539*795d594fSAndroid Build Coastguard Worker asr x2, x3, #12 540*795d594fSAndroid Build Coastguard Worker GET_VREG_OBJECT w5, w2 541*795d594fSAndroid Build Coastguard Worker str w5, [xNEW_FP, ip] 542*795d594fSAndroid Build Coastguard Worker GET_VREG w5, w2 543*795d594fSAndroid Build Coastguard Worker str w5, [x4, ip] 544*795d594fSAndroid Build Coastguard Worker sub ip, ip, #4 545*795d594fSAndroid Build Coastguard Worker3: 546*795d594fSAndroid Build Coastguard Worker ubfx x2, x3, #8, #4 547*795d594fSAndroid Build Coastguard Worker GET_VREG_OBJECT w5, w2 548*795d594fSAndroid Build Coastguard Worker str w5, [xNEW_FP, ip] 549*795d594fSAndroid Build Coastguard Worker GET_VREG w5, w2 550*795d594fSAndroid Build Coastguard Worker str w5, [x4, ip] 551*795d594fSAndroid Build Coastguard Worker sub ip, ip, #4 552*795d594fSAndroid Build Coastguard Worker2: 553*795d594fSAndroid Build Coastguard Worker ubfx x2, x3, #4, #4 554*795d594fSAndroid Build Coastguard Worker GET_VREG_OBJECT w5, w2 555*795d594fSAndroid Build Coastguard Worker str w5, [xNEW_FP, ip] 556*795d594fSAndroid Build Coastguard Worker GET_VREG w5, w2 557*795d594fSAndroid Build Coastguard Worker str w5, [x4, ip] 558*795d594fSAndroid Build Coastguard Worker .if !\is_string_init 559*795d594fSAndroid Build Coastguard Worker sub ip, ip, #4 560*795d594fSAndroid Build Coastguard Worker .endif 561*795d594fSAndroid Build Coastguard Worker1: 562*795d594fSAndroid Build Coastguard Worker .if \is_string_init 563*795d594fSAndroid Build Coastguard Worker // Ignore the first argument 564*795d594fSAndroid Build Coastguard Worker .elseif \is_static 565*795d594fSAndroid Build Coastguard Worker and x2, x3, #0xf 566*795d594fSAndroid Build Coastguard Worker GET_VREG_OBJECT w5, w2 567*795d594fSAndroid Build Coastguard Worker str w5, [xNEW_FP, ip] 568*795d594fSAndroid Build Coastguard Worker GET_VREG w5, w2 569*795d594fSAndroid Build Coastguard Worker str w5, [x4, ip] 570*795d594fSAndroid Build Coastguard Worker .else 571*795d594fSAndroid Build Coastguard Worker str w1, [xNEW_FP, ip] 572*795d594fSAndroid Build Coastguard Worker str w1, [x4, ip] 573*795d594fSAndroid Build Coastguard Worker .endif 574*795d594fSAndroid Build Coastguard Worker 575*795d594fSAndroid Build Coastguard Worker6: 576*795d594fSAndroid Build Coastguard Worker // Start executing the method. 577*795d594fSAndroid Build Coastguard Worker mov xFP, xNEW_FP 578*795d594fSAndroid Build Coastguard Worker mov xREFS, xNEW_REFS 579*795d594fSAndroid Build Coastguard Worker CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, CALLEE_SAVES_SIZE 580*795d594fSAndroid Build Coastguard Worker START_EXECUTING_INSTRUCTIONS 581*795d594fSAndroid Build Coastguard Worker.endm 582*795d594fSAndroid Build Coastguard Worker 583*795d594fSAndroid Build Coastguard Worker// Setup arguments based on a range nterp to nterp call, and start executing 584*795d594fSAndroid Build Coastguard Worker// the method. 585*795d594fSAndroid Build Coastguard Worker// - xNEW_FP: the new pointer to dex registers 586*795d594fSAndroid Build Coastguard Worker// - xNEW_REFS: the new pointer to references 587*795d594fSAndroid Build Coastguard Worker// - xPC: the new PC pointer to execute 588*795d594fSAndroid Build Coastguard Worker// - x2: number of arguments 589*795d594fSAndroid Build Coastguard Worker// - x3: first dex register 590*795d594fSAndroid Build Coastguard Worker// - x4: top of dex register array 591*795d594fSAndroid Build Coastguard Worker// - x1: receiver if non-static. 592*795d594fSAndroid Build Coastguard Worker// 593*795d594fSAndroid Build Coastguard Worker// Uses ip, ip2, x5, x6 as temporaries. 594*795d594fSAndroid Build Coastguard Worker.macro SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0 595*795d594fSAndroid Build Coastguard Worker mov ip, #-4 596*795d594fSAndroid Build Coastguard Worker .if \is_string_init 597*795d594fSAndroid Build Coastguard Worker // Ignore the first argument 598*795d594fSAndroid Build Coastguard Worker sub x2, x2, #1 599*795d594fSAndroid Build Coastguard Worker add x3, x3, #1 600*795d594fSAndroid Build Coastguard Worker .elseif !\is_static 601*795d594fSAndroid Build Coastguard Worker sub x2, x2, #1 602*795d594fSAndroid Build Coastguard Worker add x3, x3, #1 603*795d594fSAndroid Build Coastguard Worker .endif 604*795d594fSAndroid Build Coastguard Worker 605*795d594fSAndroid Build Coastguard Worker cbz x2, 2f 606*795d594fSAndroid Build Coastguard Worker add ip2, xREFS, x3, lsl #2 // pointer to first argument in reference array 607*795d594fSAndroid Build Coastguard Worker add ip2, ip2, x2, lsl #2 // pointer to last argument in reference array 608*795d594fSAndroid Build Coastguard Worker add x5, xFP, x3, lsl #2 // pointer to first argument in register array 609*795d594fSAndroid Build Coastguard Worker add x6, x5, x2, lsl #2 // pointer to last argument in register array 610*795d594fSAndroid Build Coastguard Worker1: 611*795d594fSAndroid Build Coastguard Worker ldr w7, [ip2, #-4]! 612*795d594fSAndroid Build Coastguard Worker str w7, [xNEW_FP, ip] 613*795d594fSAndroid Build Coastguard Worker sub x2, x2, 1 614*795d594fSAndroid Build Coastguard Worker ldr w7, [x6, #-4]! 615*795d594fSAndroid Build Coastguard Worker str w7, [x4, ip] 616*795d594fSAndroid Build Coastguard Worker sub ip, ip, 4 617*795d594fSAndroid Build Coastguard Worker cbnz x2, 1b 618*795d594fSAndroid Build Coastguard Worker2: 619*795d594fSAndroid Build Coastguard Worker .if \is_string_init 620*795d594fSAndroid Build Coastguard Worker // Ignore first argument 621*795d594fSAndroid Build Coastguard Worker .elseif !\is_static 622*795d594fSAndroid Build Coastguard Worker str w1, [xNEW_FP, ip] 623*795d594fSAndroid Build Coastguard Worker str w1, [x4, ip] 624*795d594fSAndroid Build Coastguard Worker .endif 625*795d594fSAndroid Build Coastguard Worker mov xFP, xNEW_FP 626*795d594fSAndroid Build Coastguard Worker mov xREFS, xNEW_REFS 627*795d594fSAndroid Build Coastguard Worker CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, CALLEE_SAVES_SIZE 628*795d594fSAndroid Build Coastguard Worker START_EXECUTING_INSTRUCTIONS 629*795d594fSAndroid Build Coastguard Worker.endm 630*795d594fSAndroid Build Coastguard Worker 631*795d594fSAndroid Build Coastguard Worker.macro GET_SHORTY dest, is_interface, is_polymorphic, is_custom 632*795d594fSAndroid Build Coastguard Worker stp x0, x1, [sp, #-16]! 633*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 634*795d594fSAndroid Build Coastguard Worker ldr x0, [sp, #16] 635*795d594fSAndroid Build Coastguard Worker mov x1, xPC 636*795d594fSAndroid Build Coastguard Worker bl NterpGetShortyFromInvokePolymorphic 637*795d594fSAndroid Build Coastguard Worker .elseif \is_custom 638*795d594fSAndroid Build Coastguard Worker ldr x0, [sp, #16] 639*795d594fSAndroid Build Coastguard Worker mov x1, xPC 640*795d594fSAndroid Build Coastguard Worker bl NterpGetShortyFromInvokeCustom 641*795d594fSAndroid Build Coastguard Worker .elseif \is_interface 642*795d594fSAndroid Build Coastguard Worker ldr x0, [sp, #16] 643*795d594fSAndroid Build Coastguard Worker FETCH w1, 1 644*795d594fSAndroid Build Coastguard Worker bl NterpGetShortyFromMethodId 645*795d594fSAndroid Build Coastguard Worker .else 646*795d594fSAndroid Build Coastguard Worker bl NterpGetShorty 647*795d594fSAndroid Build Coastguard Worker .endif 648*795d594fSAndroid Build Coastguard Worker mov \dest, x0 649*795d594fSAndroid Build Coastguard Worker ldp x0, x1, [sp], #16 650*795d594fSAndroid Build Coastguard Worker.endm 651*795d594fSAndroid Build Coastguard Worker 652*795d594fSAndroid Build Coastguard Worker.macro GET_SHORTY_SLOW_PATH dest, is_interface 653*795d594fSAndroid Build Coastguard Worker // Save all registers that can hold arguments in the fast path. 654*795d594fSAndroid Build Coastguard Worker stp x0, x1, [sp, #-32]! 655*795d594fSAndroid Build Coastguard Worker str w2, [sp, #16] 656*795d594fSAndroid Build Coastguard Worker str s0, [sp, #20] 657*795d594fSAndroid Build Coastguard Worker .if \is_interface 658*795d594fSAndroid Build Coastguard Worker ldr x0, [sp, #32] 659*795d594fSAndroid Build Coastguard Worker FETCH w1, 1 660*795d594fSAndroid Build Coastguard Worker bl NterpGetShortyFromMethodId 661*795d594fSAndroid Build Coastguard Worker .else 662*795d594fSAndroid Build Coastguard Worker bl NterpGetShorty 663*795d594fSAndroid Build Coastguard Worker .endif 664*795d594fSAndroid Build Coastguard Worker mov \dest, x0 665*795d594fSAndroid Build Coastguard Worker ldr w2, [sp, #16] 666*795d594fSAndroid Build Coastguard Worker ldr s0, [sp, #20] 667*795d594fSAndroid Build Coastguard Worker ldp x0, x1, [sp], #32 668*795d594fSAndroid Build Coastguard Worker.endm 669*795d594fSAndroid Build Coastguard Worker 670*795d594fSAndroid Build Coastguard Worker// Input: x0 contains the ArtMethod 671*795d594fSAndroid Build Coastguard Worker// Output: x8 contains the code item 672*795d594fSAndroid Build Coastguard Worker.macro GET_CODE_ITEM 673*795d594fSAndroid Build Coastguard Worker ldr x8, [x0, #ART_METHOD_DATA_OFFSET_64] 674*795d594fSAndroid Build Coastguard Worker.endm 675*795d594fSAndroid Build Coastguard Worker 676*795d594fSAndroid Build Coastguard Worker.macro DO_ENTRY_POINT_CHECK call_compiled_code 677*795d594fSAndroid Build Coastguard Worker // On entry, the method is x0, the instance is x1 678*795d594fSAndroid Build Coastguard Worker adr x2, ExecuteNterpImpl 679*795d594fSAndroid Build Coastguard Worker ldr x3, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64] 680*795d594fSAndroid Build Coastguard Worker cmp x2, x3 681*795d594fSAndroid Build Coastguard Worker b.ne \call_compiled_code 682*795d594fSAndroid Build Coastguard Worker.endm 683*795d594fSAndroid Build Coastguard Worker 684*795d594fSAndroid Build Coastguard Worker.macro UPDATE_REGISTERS_FOR_STRING_INIT old_value, new_value 685*795d594fSAndroid Build Coastguard Worker mov wip, wzr 686*795d594fSAndroid Build Coastguard Worker1: 687*795d594fSAndroid Build Coastguard Worker GET_VREG_OBJECT wip2, wip 688*795d594fSAndroid Build Coastguard Worker cmp wip2, \old_value 689*795d594fSAndroid Build Coastguard Worker b.ne 2f 690*795d594fSAndroid Build Coastguard Worker SET_VREG_OBJECT \new_value, wip 691*795d594fSAndroid Build Coastguard Worker2: 692*795d594fSAndroid Build Coastguard Worker add wip, wip, #1 693*795d594fSAndroid Build Coastguard Worker add ip2, xREFS, wip, uxtw #2 694*795d594fSAndroid Build Coastguard Worker cmp ip2, xFP 695*795d594fSAndroid Build Coastguard Worker b.ne 1b 696*795d594fSAndroid Build Coastguard Worker.endm 697*795d594fSAndroid Build Coastguard Worker 698*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected register, 699*795d594fSAndroid Build Coastguard Worker// fetching values based on a non-range invoke. 700*795d594fSAndroid Build Coastguard Worker// Uses ip and ip2. 701*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_LOADING_FPS dreg, sreg, inst, shorty, arg_index, finished 702*795d594fSAndroid Build Coastguard Worker1: // LOOP 703*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 704*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 705*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto FOUND_DOUBLE 706*795d594fSAndroid Build Coastguard Worker b.eq 2f 707*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto FOUND_FLOAT 708*795d594fSAndroid Build Coastguard Worker b.eq 3f 709*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 710*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 711*795d594fSAndroid Build Coastguard Worker // Handle extra argument in arg array taken by a long. 712*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip != 'J') goto LOOP 713*795d594fSAndroid Build Coastguard Worker b.ne 1b 714*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 715*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 716*795d594fSAndroid Build Coastguard Worker b 1b // goto LOOP 717*795d594fSAndroid Build Coastguard Worker2: // FOUND_DOUBLE 718*795d594fSAndroid Build Coastguard Worker and ip, \inst, #0xf 719*795d594fSAndroid Build Coastguard Worker GET_VREG wip, wip 720*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 721*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 722*795d594fSAndroid Build Coastguard Worker cmp \arg_index, #4 723*795d594fSAndroid Build Coastguard Worker b.eq 5f 724*795d594fSAndroid Build Coastguard Worker and ip2, \inst, #0xf 725*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 726*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 727*795d594fSAndroid Build Coastguard Worker b 6f 728*795d594fSAndroid Build Coastguard Worker5: 729*795d594fSAndroid Build Coastguard Worker // TODO: Extract from wINST here and below? (Requires using a different register 730*795d594fSAndroid Build Coastguard Worker // in the COMMON_INVOKE_NON_RANGE.) 731*795d594fSAndroid Build Coastguard Worker FETCH_B wip2, 0, 1 732*795d594fSAndroid Build Coastguard Worker and wip2, wip2, #0xf 733*795d594fSAndroid Build Coastguard Worker6: 734*795d594fSAndroid Build Coastguard Worker GET_VREG wip2, wip2 735*795d594fSAndroid Build Coastguard Worker add ip, ip, ip2, lsl #32 736*795d594fSAndroid Build Coastguard Worker fmov \dreg, ip 737*795d594fSAndroid Build Coastguard Worker b 4f 738*795d594fSAndroid Build Coastguard Worker3: // FOUND_FLOAT 739*795d594fSAndroid Build Coastguard Worker cmp \arg_index, #4 740*795d594fSAndroid Build Coastguard Worker b.eq 7f 741*795d594fSAndroid Build Coastguard Worker and ip, \inst, #0xf 742*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 743*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 744*795d594fSAndroid Build Coastguard Worker b 8f 745*795d594fSAndroid Build Coastguard Worker7: 746*795d594fSAndroid Build Coastguard Worker FETCH_B wip, 0, 1 747*795d594fSAndroid Build Coastguard Worker and wip, wip, #0xf 748*795d594fSAndroid Build Coastguard Worker8: 749*795d594fSAndroid Build Coastguard Worker GET_VREG \sreg, wip 750*795d594fSAndroid Build Coastguard Worker4: 751*795d594fSAndroid Build Coastguard Worker.endm 752*795d594fSAndroid Build Coastguard Worker 753*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected register, 754*795d594fSAndroid Build Coastguard Worker// fetching values based on a non-range invoke. 755*795d594fSAndroid Build Coastguard Worker// Uses ip and ip2. 756*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_LOADING_GPRS gpr_reg64, gpr_reg32, inst, shorty, arg_index, finished 757*795d594fSAndroid Build Coastguard Worker1: // LOOP 758*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 759*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 760*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip == 'J') goto FOUND_LONG 761*795d594fSAndroid Build Coastguard Worker b.eq 2f 762*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto SKIP_FLOAT 763*795d594fSAndroid Build Coastguard Worker b.eq 3f 764*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto SKIP_DOUBLE 765*795d594fSAndroid Build Coastguard Worker b.eq 4f 766*795d594fSAndroid Build Coastguard Worker cmp \arg_index, #4 767*795d594fSAndroid Build Coastguard Worker b.eq 7f 768*795d594fSAndroid Build Coastguard Worker and ip, \inst, #0xf 769*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 770*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 771*795d594fSAndroid Build Coastguard Worker b 8f 772*795d594fSAndroid Build Coastguard Worker7: 773*795d594fSAndroid Build Coastguard Worker FETCH_B wip, 0, 1 774*795d594fSAndroid Build Coastguard Worker and wip, wip, #0xf 775*795d594fSAndroid Build Coastguard Worker8: 776*795d594fSAndroid Build Coastguard Worker GET_VREG \gpr_reg32, wip 777*795d594fSAndroid Build Coastguard Worker b 5f 778*795d594fSAndroid Build Coastguard Worker2: // FOUND_LONG 779*795d594fSAndroid Build Coastguard Worker and ip, \inst, #0xf 780*795d594fSAndroid Build Coastguard Worker GET_VREG wip, wip 781*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 782*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 783*795d594fSAndroid Build Coastguard Worker cmp \arg_index, #4 784*795d594fSAndroid Build Coastguard Worker b.eq 9f 785*795d594fSAndroid Build Coastguard Worker and ip2, \inst, #0xf 786*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 787*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 788*795d594fSAndroid Build Coastguard Worker b 10f 789*795d594fSAndroid Build Coastguard Worker9: 790*795d594fSAndroid Build Coastguard Worker FETCH_B wip2, 0, 1 791*795d594fSAndroid Build Coastguard Worker and wip2, wip2, #0xf 792*795d594fSAndroid Build Coastguard Worker10: 793*795d594fSAndroid Build Coastguard Worker GET_VREG wip2, wip2 794*795d594fSAndroid Build Coastguard Worker add \gpr_reg64, ip, ip2, lsl #32 795*795d594fSAndroid Build Coastguard Worker b 5f 796*795d594fSAndroid Build Coastguard Worker3: // SKIP_FLOAT 797*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 798*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 799*795d594fSAndroid Build Coastguard Worker b 1b 800*795d594fSAndroid Build Coastguard Worker4: // SKIP_DOUBLE 801*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 802*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 803*795d594fSAndroid Build Coastguard Worker cmp \arg_index, #4 804*795d594fSAndroid Build Coastguard Worker b.eq 1b 805*795d594fSAndroid Build Coastguard Worker lsr \inst, \inst, #4 806*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 807*795d594fSAndroid Build Coastguard Worker b 1b 808*795d594fSAndroid Build Coastguard Worker5: 809*795d594fSAndroid Build Coastguard Worker.endm 810*795d594fSAndroid Build Coastguard Worker 811*795d594fSAndroid Build Coastguard Worker.macro SETUP_RETURN_VALUE shorty 812*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty] 813*795d594fSAndroid Build Coastguard Worker cmp ip, #68 // Test if result type char == 'D'. 814*795d594fSAndroid Build Coastguard Worker b.eq 1f 815*795d594fSAndroid Build Coastguard Worker cmp ip, #70 // Test if result type char == 'F'. 816*795d594fSAndroid Build Coastguard Worker b.ne 2f 817*795d594fSAndroid Build Coastguard Worker fmov w0, s0 818*795d594fSAndroid Build Coastguard Worker b 2f 819*795d594fSAndroid Build Coastguard Worker1: 820*795d594fSAndroid Build Coastguard Worker fmov x0, d0 821*795d594fSAndroid Build Coastguard Worker2: 822*795d594fSAndroid Build Coastguard Worker.endm 823*795d594fSAndroid Build Coastguard Worker 824*795d594fSAndroid Build Coastguard Worker.macro COMMON_INVOKE_NON_RANGE is_static=0, is_interface=0, suffix="", is_string_init=0, is_polymorphic=0, is_custom=0 825*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 826*795d594fSAndroid Build Coastguard Worker // We always go to compiled code for polymorphic calls. 827*795d594fSAndroid Build Coastguard Worker .elseif \is_custom 828*795d594fSAndroid Build Coastguard Worker // We always go to compiled code for custom calls. 829*795d594fSAndroid Build Coastguard Worker .else 830*795d594fSAndroid Build Coastguard Worker DO_ENTRY_POINT_CHECK .Lcall_compiled_code_\suffix 831*795d594fSAndroid Build Coastguard Worker GET_CODE_ITEM 832*795d594fSAndroid Build Coastguard Worker .if \is_string_init 833*795d594fSAndroid Build Coastguard Worker bl nterp_to_nterp_string_init_non_range 834*795d594fSAndroid Build Coastguard Worker .elseif \is_static 835*795d594fSAndroid Build Coastguard Worker bl nterp_to_nterp_static_non_range 836*795d594fSAndroid Build Coastguard Worker .else 837*795d594fSAndroid Build Coastguard Worker bl nterp_to_nterp_instance_non_range 838*795d594fSAndroid Build Coastguard Worker .endif 839*795d594fSAndroid Build Coastguard Worker b .Ldone_return_\suffix 840*795d594fSAndroid Build Coastguard Worker .endif 841*795d594fSAndroid Build Coastguard Worker 842*795d594fSAndroid Build Coastguard Worker.Lcall_compiled_code_\suffix: 843*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 844*795d594fSAndroid Build Coastguard Worker // No fast path for polymorphic calls. 845*795d594fSAndroid Build Coastguard Worker .elseif \is_custom 846*795d594fSAndroid Build Coastguard Worker // No fast path for custom calls. 847*795d594fSAndroid Build Coastguard Worker .elseif \is_string_init 848*795d594fSAndroid Build Coastguard Worker // No fast path for string.init. 849*795d594fSAndroid Build Coastguard Worker .else 850*795d594fSAndroid Build Coastguard Worker ldr wip, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET] 851*795d594fSAndroid Build Coastguard Worker tbz wip, #ART_METHOD_NTERP_INVOKE_FAST_PATH_FLAG_BIT, .Lfast_path_with_few_args_\suffix 852*795d594fSAndroid Build Coastguard Worker FETCH_B wip2, 0, 1 853*795d594fSAndroid Build Coastguard Worker asr ip, ip2, #4 854*795d594fSAndroid Build Coastguard Worker .if \is_static 855*795d594fSAndroid Build Coastguard Worker cbz ip, .Linvoke_fast_path_\suffix 856*795d594fSAndroid Build Coastguard Worker .else 857*795d594fSAndroid Build Coastguard Worker cmp ip, #1 858*795d594fSAndroid Build Coastguard Worker b.eq .Linvoke_fast_path_\suffix 859*795d594fSAndroid Build Coastguard Worker .endif 860*795d594fSAndroid Build Coastguard Worker FETCH w8, 2 861*795d594fSAndroid Build Coastguard Worker cmp ip, #2 862*795d594fSAndroid Build Coastguard Worker .if \is_static 863*795d594fSAndroid Build Coastguard Worker b.lt .Lone_arg_fast_path_\suffix 864*795d594fSAndroid Build Coastguard Worker .endif 865*795d594fSAndroid Build Coastguard Worker b.eq .Ltwo_args_fast_path_\suffix 866*795d594fSAndroid Build Coastguard Worker cmp ip, #4 867*795d594fSAndroid Build Coastguard Worker b.lt .Lthree_args_fast_path_\suffix 868*795d594fSAndroid Build Coastguard Worker b.eq .Lfour_args_fast_path_\suffix 869*795d594fSAndroid Build Coastguard Worker 870*795d594fSAndroid Build Coastguard Worker and ip, ip2, #15 871*795d594fSAndroid Build Coastguard Worker GET_VREG w5, wip 872*795d594fSAndroid Build Coastguard Worker.Lfour_args_fast_path_\suffix: 873*795d594fSAndroid Build Coastguard Worker asr ip, x8, #12 874*795d594fSAndroid Build Coastguard Worker GET_VREG w4, wip 875*795d594fSAndroid Build Coastguard Worker.Lthree_args_fast_path_\suffix: 876*795d594fSAndroid Build Coastguard Worker ubfx ip, x8, #8, #4 877*795d594fSAndroid Build Coastguard Worker GET_VREG w3, wip 878*795d594fSAndroid Build Coastguard Worker.Ltwo_args_fast_path_\suffix: 879*795d594fSAndroid Build Coastguard Worker ubfx ip, x8, #4, #4 880*795d594fSAndroid Build Coastguard Worker GET_VREG w2, wip 881*795d594fSAndroid Build Coastguard Worker.Lone_arg_fast_path_\suffix: 882*795d594fSAndroid Build Coastguard Worker .if \is_static 883*795d594fSAndroid Build Coastguard Worker and ip, x8, #0xf 884*795d594fSAndroid Build Coastguard Worker GET_VREG w1, wip 885*795d594fSAndroid Build Coastguard Worker .else 886*795d594fSAndroid Build Coastguard Worker // First argument already in w1. 887*795d594fSAndroid Build Coastguard Worker .endif 888*795d594fSAndroid Build Coastguard Worker.Linvoke_fast_path_\suffix: 889*795d594fSAndroid Build Coastguard Worker .if \is_interface 890*795d594fSAndroid Build Coastguard Worker // Setup hidden argument. 891*795d594fSAndroid Build Coastguard Worker mov ip2, x26 892*795d594fSAndroid Build Coastguard Worker .endif 893*795d594fSAndroid Build Coastguard Worker ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64] 894*795d594fSAndroid Build Coastguard Worker blr lr 895*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 3 896*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 897*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 898*795d594fSAndroid Build Coastguard Worker 899*795d594fSAndroid Build Coastguard Worker.Lfast_path_with_few_args_\suffix: 900*795d594fSAndroid Build Coastguard Worker // Fast path when we have zero or one argument (modulo 'this'). If there 901*795d594fSAndroid Build Coastguard Worker // is one argument, we can put it in both floating point and core register. 902*795d594fSAndroid Build Coastguard Worker FETCH_B w2, 0, 1 903*795d594fSAndroid Build Coastguard Worker .if \is_static 904*795d594fSAndroid Build Coastguard Worker cmp w2, #(2 << 4) 905*795d594fSAndroid Build Coastguard Worker .else 906*795d594fSAndroid Build Coastguard Worker cmp w2, #(3 << 4) 907*795d594fSAndroid Build Coastguard Worker .endif 908*795d594fSAndroid Build Coastguard Worker b.ge .Lget_shorty_\suffix 909*795d594fSAndroid Build Coastguard Worker .if \is_static 910*795d594fSAndroid Build Coastguard Worker tbz w2, #4, .Linvoke_with_few_args_\suffix 911*795d594fSAndroid Build Coastguard Worker .else 912*795d594fSAndroid Build Coastguard Worker tbnz w2, #4, .Linvoke_with_few_args_\suffix 913*795d594fSAndroid Build Coastguard Worker .endif 914*795d594fSAndroid Build Coastguard Worker FETCH w2, 2 915*795d594fSAndroid Build Coastguard Worker .if \is_static 916*795d594fSAndroid Build Coastguard Worker and w2, w2, #0xf // dex register of first argument 917*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w2 918*795d594fSAndroid Build Coastguard Worker fmov s0, w1 919*795d594fSAndroid Build Coastguard Worker .else 920*795d594fSAndroid Build Coastguard Worker ubfx x2, x2, #4, #4 // dex register of second argument 921*795d594fSAndroid Build Coastguard Worker GET_VREG w2, w2 922*795d594fSAndroid Build Coastguard Worker fmov s0, w2 923*795d594fSAndroid Build Coastguard Worker .endif 924*795d594fSAndroid Build Coastguard Worker.Linvoke_with_few_args_\suffix: 925*795d594fSAndroid Build Coastguard Worker // Check if the next instruction is move-result or move-result-wide. 926*795d594fSAndroid Build Coastguard Worker // If it is, we fetch the shorty and jump to the regular invocation. 927*795d594fSAndroid Build Coastguard Worker FETCH w27, 3 928*795d594fSAndroid Build Coastguard Worker and ip, x27, #0xfe 929*795d594fSAndroid Build Coastguard Worker cmp ip, #0x0a 930*795d594fSAndroid Build Coastguard Worker b.eq .Lget_shorty_and_invoke_\suffix 931*795d594fSAndroid Build Coastguard Worker .if \is_interface 932*795d594fSAndroid Build Coastguard Worker // Setup hidden argument. 933*795d594fSAndroid Build Coastguard Worker mov ip2, x26 934*795d594fSAndroid Build Coastguard Worker .endif 935*795d594fSAndroid Build Coastguard Worker ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64] 936*795d594fSAndroid Build Coastguard Worker blr lr 937*795d594fSAndroid Build Coastguard Worker # TODO: Use some other register for shorty and prefetch the instruction directly to wINST. 938*795d594fSAndroid Build Coastguard Worker mov xINST, x27 939*795d594fSAndroid Build Coastguard Worker ADVANCE 3 940*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 941*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 942*795d594fSAndroid Build Coastguard Worker.Lget_shorty_and_invoke_\suffix: 943*795d594fSAndroid Build Coastguard Worker GET_SHORTY_SLOW_PATH xINST, \is_interface 944*795d594fSAndroid Build Coastguard Worker b .Lgpr_setup_finished_\suffix 945*795d594fSAndroid Build Coastguard Worker .endif 946*795d594fSAndroid Build Coastguard Worker 947*795d594fSAndroid Build Coastguard Worker.Lget_shorty_\suffix: 948*795d594fSAndroid Build Coastguard Worker GET_SHORTY xINST, \is_interface, \is_polymorphic, \is_custom 949*795d594fSAndroid Build Coastguard Worker // From this point: 950*795d594fSAndroid Build Coastguard Worker // - xINST contains shorty (in callee-save to switch over return value after call). 951*795d594fSAndroid Build Coastguard Worker // - x0 contains method 952*795d594fSAndroid Build Coastguard Worker // - x1 contains 'this' pointer for instance method. 953*795d594fSAndroid Build Coastguard Worker // - for interface calls, x26 contains the interface method. 954*795d594fSAndroid Build Coastguard Worker add x9, xINST, #1 // shorty + 1 ; ie skip return arg character 955*795d594fSAndroid Build Coastguard Worker FETCH w11, 2 // arguments 956*795d594fSAndroid Build Coastguard Worker .if \is_string_init 957*795d594fSAndroid Build Coastguard Worker lsr x11, x11, #4 958*795d594fSAndroid Build Coastguard Worker mov x10, #1 // ignore first argument 959*795d594fSAndroid Build Coastguard Worker .elseif \is_static 960*795d594fSAndroid Build Coastguard Worker mov x10, xzr // arg_index 961*795d594fSAndroid Build Coastguard Worker .else 962*795d594fSAndroid Build Coastguard Worker lsr x11, x11, #4 963*795d594fSAndroid Build Coastguard Worker mov x10, #1 // ignore first argument 964*795d594fSAndroid Build Coastguard Worker .endif 965*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_FPS d0, s0, x11, x9, x10, .Lxmm_setup_finished_\suffix 966*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_FPS d1, s1, x11, x9, x10, .Lxmm_setup_finished_\suffix 967*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_FPS d2, s2, x11, x9, x10, .Lxmm_setup_finished_\suffix 968*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_FPS d3, s3, x11, x9, x10, .Lxmm_setup_finished_\suffix 969*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_FPS d4, s4, x11, x9, x10, .Lxmm_setup_finished_\suffix 970*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished_\suffix: 971*795d594fSAndroid Build Coastguard Worker add x9, xINST, #1 // shorty + 1 ; ie skip return arg character 972*795d594fSAndroid Build Coastguard Worker FETCH w11, 2 // arguments 973*795d594fSAndroid Build Coastguard Worker .if \is_string_init 974*795d594fSAndroid Build Coastguard Worker lsr x11, x11, #4 975*795d594fSAndroid Build Coastguard Worker mov x10, #1 // ignore first argument 976*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_GPRS x1, w1, x11, x9, x10, .Lgpr_setup_finished_\suffix 977*795d594fSAndroid Build Coastguard Worker .elseif \is_static 978*795d594fSAndroid Build Coastguard Worker mov x10, xzr // arg_index 979*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_GPRS x1, w1, x11, x9, x10, .Lgpr_setup_finished_\suffix 980*795d594fSAndroid Build Coastguard Worker .else 981*795d594fSAndroid Build Coastguard Worker lsr x11, x11, #4 982*795d594fSAndroid Build Coastguard Worker mov x10, #1 // ignore first argument 983*795d594fSAndroid Build Coastguard Worker .endif 984*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_GPRS x2, w2, x11, x9, x10, .Lgpr_setup_finished_\suffix 985*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_GPRS x3, w3, x11, x9, x10, .Lgpr_setup_finished_\suffix 986*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_GPRS x4, w4, x11, x9, x10, .Lgpr_setup_finished_\suffix 987*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_LOADING_GPRS x5, w5, x11, x9, x10, .Lgpr_setup_finished_\suffix 988*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished_\suffix: 989*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 990*795d594fSAndroid Build Coastguard Worker bl art_quick_invoke_polymorphic 991*795d594fSAndroid Build Coastguard Worker .elseif \is_custom 992*795d594fSAndroid Build Coastguard Worker bl art_quick_invoke_custom 993*795d594fSAndroid Build Coastguard Worker .else 994*795d594fSAndroid Build Coastguard Worker .if \is_interface 995*795d594fSAndroid Build Coastguard Worker // Setup hidden argument. 996*795d594fSAndroid Build Coastguard Worker mov ip2, x26 997*795d594fSAndroid Build Coastguard Worker .endif 998*795d594fSAndroid Build Coastguard Worker ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64] 999*795d594fSAndroid Build Coastguard Worker blr lr 1000*795d594fSAndroid Build Coastguard Worker .endif 1001*795d594fSAndroid Build Coastguard Worker SETUP_RETURN_VALUE xINST 1002*795d594fSAndroid Build Coastguard Worker.Ldone_return_\suffix: 1003*795d594fSAndroid Build Coastguard Worker /* resume execution of caller */ 1004*795d594fSAndroid Build Coastguard Worker .if \is_string_init 1005*795d594fSAndroid Build Coastguard Worker FETCH w11, 2 // arguments 1006*795d594fSAndroid Build Coastguard Worker and x11, x11, #0xf 1007*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w11 1008*795d594fSAndroid Build Coastguard Worker UPDATE_REGISTERS_FOR_STRING_INIT w1, w0 1009*795d594fSAndroid Build Coastguard Worker .endif 1010*795d594fSAndroid Build Coastguard Worker 1011*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 1012*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 4 1013*795d594fSAndroid Build Coastguard Worker .else 1014*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 3 1015*795d594fSAndroid Build Coastguard Worker .endif 1016*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 1017*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 1018*795d594fSAndroid Build Coastguard Worker.endm 1019*795d594fSAndroid Build Coastguard Worker 1020*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected register, 1021*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke. 1022*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary. 1023*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_SHORTY_LOADING_FPS dreg, sreg, shorty, arg_index, stack_index, finished 1024*795d594fSAndroid Build Coastguard Worker1: // LOOP 1025*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 1026*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 1027*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto FOUND_DOUBLE 1028*795d594fSAndroid Build Coastguard Worker b.eq 2f 1029*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto FOUND_FLOAT 1030*795d594fSAndroid Build Coastguard Worker b.eq 3f 1031*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1032*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1033*795d594fSAndroid Build Coastguard Worker // Handle extra argument in arg array taken by a long. 1034*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip != 'J') goto LOOP 1035*795d594fSAndroid Build Coastguard Worker b.ne 1b 1036*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1037*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1038*795d594fSAndroid Build Coastguard Worker b 1b // goto LOOP 1039*795d594fSAndroid Build Coastguard Worker2: // FOUND_DOUBLE 1040*795d594fSAndroid Build Coastguard Worker GET_VREG_DOUBLE \dreg, \arg_index 1041*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #2 1042*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #2 1043*795d594fSAndroid Build Coastguard Worker b 4f 1044*795d594fSAndroid Build Coastguard Worker3: // FOUND_FLOAT 1045*795d594fSAndroid Build Coastguard Worker GET_VREG \sreg, \arg_index 1046*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1047*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1048*795d594fSAndroid Build Coastguard Worker4: 1049*795d594fSAndroid Build Coastguard Worker.endm 1050*795d594fSAndroid Build Coastguard Worker 1051*795d594fSAndroid Build Coastguard Worker// Puts the next floating point argument into the expected stack slot, 1052*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke. 1053*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary. 1054*795d594fSAndroid Build Coastguard Worker// 1055*795d594fSAndroid Build Coastguard Worker// TODO: We could just copy all the vregs to the stack slots in a simple loop 1056*795d594fSAndroid Build Coastguard Worker// without looking at the shorty at all. (We could also drop 1057*795d594fSAndroid Build Coastguard Worker// the "stack_index" from the macros for loading registers.) We could also do 1058*795d594fSAndroid Build Coastguard Worker// that conditionally if argument word count > 6; otherwise we know that all 1059*795d594fSAndroid Build Coastguard Worker// args fit into registers. 1060*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_FPs shorty, arg_index, stack_index, finished 1061*795d594fSAndroid Build Coastguard Worker1: // LOOP 1062*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 1063*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 1064*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto FOUND_DOUBLE 1065*795d594fSAndroid Build Coastguard Worker b.eq 2f 1066*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto FOUND_FLOAT 1067*795d594fSAndroid Build Coastguard Worker b.eq 3f 1068*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1069*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1070*795d594fSAndroid Build Coastguard Worker // Handle extra argument in arg array taken by a long. 1071*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip != 'J') goto LOOP 1072*795d594fSAndroid Build Coastguard Worker b.ne 1b 1073*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1074*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1075*795d594fSAndroid Build Coastguard Worker b 1b // goto LOOP 1076*795d594fSAndroid Build Coastguard Worker2: // FOUND_DOUBLE 1077*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE ip, \arg_index 1078*795d594fSAndroid Build Coastguard Worker add ip2, sp, \stack_index, uxtw #2 1079*795d594fSAndroid Build Coastguard Worker str ip, [ip2] 1080*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #2 1081*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #2 1082*795d594fSAndroid Build Coastguard Worker b 1b 1083*795d594fSAndroid Build Coastguard Worker3: // FOUND_FLOAT 1084*795d594fSAndroid Build Coastguard Worker GET_VREG wip, \arg_index 1085*795d594fSAndroid Build Coastguard Worker str wip, [sp, \stack_index, uxtw #2] 1086*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1087*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1088*795d594fSAndroid Build Coastguard Worker b 1b 1089*795d594fSAndroid Build Coastguard Worker.endm 1090*795d594fSAndroid Build Coastguard Worker 1091*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected register, 1092*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke. 1093*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary. 1094*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_SHORTY_LOADING_GPRS reg64, reg32, shorty, arg_index, stack_index, finished 1095*795d594fSAndroid Build Coastguard Worker1: // LOOP 1096*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 1097*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 1098*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip == 'J') goto FOUND_LONG 1099*795d594fSAndroid Build Coastguard Worker b.eq 2f 1100*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto SKIP_FLOAT 1101*795d594fSAndroid Build Coastguard Worker b.eq 3f 1102*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto SKIP_DOUBLE 1103*795d594fSAndroid Build Coastguard Worker b.eq 4f 1104*795d594fSAndroid Build Coastguard Worker GET_VREG \reg32, \arg_index 1105*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1106*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1107*795d594fSAndroid Build Coastguard Worker b 5f 1108*795d594fSAndroid Build Coastguard Worker2: // FOUND_LONG 1109*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE \reg64, \arg_index 1110*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #2 1111*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #2 1112*795d594fSAndroid Build Coastguard Worker b 5f 1113*795d594fSAndroid Build Coastguard Worker3: // SKIP_FLOAT 1114*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1115*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1116*795d594fSAndroid Build Coastguard Worker b 1b 1117*795d594fSAndroid Build Coastguard Worker4: // SKIP_DOUBLE 1118*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #2 1119*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #2 1120*795d594fSAndroid Build Coastguard Worker b 1b 1121*795d594fSAndroid Build Coastguard Worker5: 1122*795d594fSAndroid Build Coastguard Worker.endm 1123*795d594fSAndroid Build Coastguard Worker 1124*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object argument in the expected stack slot, 1125*795d594fSAndroid Build Coastguard Worker// fetching values based on a range invoke. 1126*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary. 1127*795d594fSAndroid Build Coastguard Worker.macro LOOP_RANGE_OVER_INTs shorty, arg_index, stack_index, finished 1128*795d594fSAndroid Build Coastguard Worker1: // LOOP 1129*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 1130*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 1131*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip == 'J') goto FOUND_LONG 1132*795d594fSAndroid Build Coastguard Worker b.eq 2f 1133*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto SKIP_FLOAT 1134*795d594fSAndroid Build Coastguard Worker b.eq 3f 1135*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto SKIP_DOUBLE 1136*795d594fSAndroid Build Coastguard Worker b.eq 4f 1137*795d594fSAndroid Build Coastguard Worker GET_VREG wip, \arg_index 1138*795d594fSAndroid Build Coastguard Worker str wip, [sp, \stack_index, uxtw #2] 1139*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1140*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1141*795d594fSAndroid Build Coastguard Worker b 1b 1142*795d594fSAndroid Build Coastguard Worker2: // FOUND_LONG 1143*795d594fSAndroid Build Coastguard Worker GET_VREG_WIDE ip, \arg_index 1144*795d594fSAndroid Build Coastguard Worker add ip2, sp, \stack_index, uxtw #2 1145*795d594fSAndroid Build Coastguard Worker str ip, [ip2] 1146*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #2 1147*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #2 1148*795d594fSAndroid Build Coastguard Worker b 1b 1149*795d594fSAndroid Build Coastguard Worker3: // SKIP_FLOAT 1150*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #1 1151*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #1 1152*795d594fSAndroid Build Coastguard Worker b 1b 1153*795d594fSAndroid Build Coastguard Worker4: // SKIP_DOUBLE 1154*795d594fSAndroid Build Coastguard Worker add \arg_index, \arg_index, #2 1155*795d594fSAndroid Build Coastguard Worker add \stack_index, \stack_index, #2 1156*795d594fSAndroid Build Coastguard Worker b 1b 1157*795d594fSAndroid Build Coastguard Worker.endm 1158*795d594fSAndroid Build Coastguard Worker 1159*795d594fSAndroid Build Coastguard Worker.macro COMMON_INVOKE_RANGE is_static=0, is_interface=0, suffix="", is_string_init=0, is_polymorphic=0, is_custom=0 1160*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 1161*795d594fSAndroid Build Coastguard Worker // We always go to compiled code for polymorphic calls. 1162*795d594fSAndroid Build Coastguard Worker .elseif \is_custom 1163*795d594fSAndroid Build Coastguard Worker // We always go to compiled code for custom calls. 1164*795d594fSAndroid Build Coastguard Worker .else 1165*795d594fSAndroid Build Coastguard Worker DO_ENTRY_POINT_CHECK .Lcall_compiled_code_range_\suffix 1166*795d594fSAndroid Build Coastguard Worker GET_CODE_ITEM 1167*795d594fSAndroid Build Coastguard Worker .if \is_string_init 1168*795d594fSAndroid Build Coastguard Worker bl nterp_to_nterp_string_init_range 1169*795d594fSAndroid Build Coastguard Worker .elseif \is_static 1170*795d594fSAndroid Build Coastguard Worker bl nterp_to_nterp_static_range 1171*795d594fSAndroid Build Coastguard Worker .else 1172*795d594fSAndroid Build Coastguard Worker bl nterp_to_nterp_instance_range 1173*795d594fSAndroid Build Coastguard Worker .endif 1174*795d594fSAndroid Build Coastguard Worker b .Ldone_return_range_\suffix 1175*795d594fSAndroid Build Coastguard Worker .endif 1176*795d594fSAndroid Build Coastguard Worker 1177*795d594fSAndroid Build Coastguard Worker.Lcall_compiled_code_range_\suffix: 1178*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 1179*795d594fSAndroid Build Coastguard Worker // No fast path for polymorphic calls. 1180*795d594fSAndroid Build Coastguard Worker .elseif \is_custom 1181*795d594fSAndroid Build Coastguard Worker // No fast path for custom calls. 1182*795d594fSAndroid Build Coastguard Worker .elseif \is_string_init 1183*795d594fSAndroid Build Coastguard Worker // No fast path for string.init. 1184*795d594fSAndroid Build Coastguard Worker .else 1185*795d594fSAndroid Build Coastguard Worker ldr wip, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET] 1186*795d594fSAndroid Build Coastguard Worker tbz wip, #ART_METHOD_NTERP_INVOKE_FAST_PATH_FLAG_BIT, .Lfast_path_with_few_args_range_\suffix 1187*795d594fSAndroid Build Coastguard Worker FETCH_B wip2, 0, 1 // Number of arguments 1188*795d594fSAndroid Build Coastguard Worker .if \is_static 1189*795d594fSAndroid Build Coastguard Worker cbz ip2, .Linvoke_fast_path_range_\suffix 1190*795d594fSAndroid Build Coastguard Worker .else 1191*795d594fSAndroid Build Coastguard Worker cmp ip2, #1 1192*795d594fSAndroid Build Coastguard Worker b.eq .Linvoke_fast_path_range_\suffix 1193*795d594fSAndroid Build Coastguard Worker .endif 1194*795d594fSAndroid Build Coastguard Worker FETCH wip, 2 // dex register of first argument 1195*795d594fSAndroid Build Coastguard Worker add x8, xFP, wip, uxtw #2 // location of first dex register value 1196*795d594fSAndroid Build Coastguard Worker cmp ip2, #2 1197*795d594fSAndroid Build Coastguard Worker .if \is_static 1198*795d594fSAndroid Build Coastguard Worker b.lt .Lone_arg_fast_path_range_\suffix 1199*795d594fSAndroid Build Coastguard Worker .endif 1200*795d594fSAndroid Build Coastguard Worker b.eq .Ltwo_args_fast_path_range_\suffix 1201*795d594fSAndroid Build Coastguard Worker cmp ip2, #4 1202*795d594fSAndroid Build Coastguard Worker b.lt .Lthree_args_fast_path_range_\suffix 1203*795d594fSAndroid Build Coastguard Worker b.eq .Lfour_args_fast_path_range_\suffix 1204*795d594fSAndroid Build Coastguard Worker cmp ip2, #6 1205*795d594fSAndroid Build Coastguard Worker b.lt .Lfive_args_fast_path_range_\suffix 1206*795d594fSAndroid Build Coastguard Worker b.eq .Lsix_args_fast_path_range_\suffix 1207*795d594fSAndroid Build Coastguard Worker cmp ip2, #7 1208*795d594fSAndroid Build Coastguard Worker b.eq .Lseven_args_fast_path_range_\suffix 1209*795d594fSAndroid Build Coastguard Worker // Setup x8 to point to the stack location of parameters we do not need 1210*795d594fSAndroid Build Coastguard Worker // to put parameters in. 1211*795d594fSAndroid Build Coastguard Worker add x9, sp, #8 // Add space for the ArtMethod 1212*795d594fSAndroid Build Coastguard Worker 1213*795d594fSAndroid Build Coastguard Worker.Lloop_over_fast_path_range_\suffix: 1214*795d594fSAndroid Build Coastguard Worker sub ip2, ip2, #1 1215*795d594fSAndroid Build Coastguard Worker ldr wip, [x8, ip2, lsl #2] 1216*795d594fSAndroid Build Coastguard Worker str wip, [x9, ip2, lsl #2] 1217*795d594fSAndroid Build Coastguard Worker cmp ip2, #7 1218*795d594fSAndroid Build Coastguard Worker b.ne .Lloop_over_fast_path_range_\suffix 1219*795d594fSAndroid Build Coastguard Worker 1220*795d594fSAndroid Build Coastguard Worker.Lseven_args_fast_path_range_\suffix: 1221*795d594fSAndroid Build Coastguard Worker ldr w7, [x8, #24] 1222*795d594fSAndroid Build Coastguard Worker.Lsix_args_fast_path_range_\suffix: 1223*795d594fSAndroid Build Coastguard Worker ldr w6, [x8, #20] 1224*795d594fSAndroid Build Coastguard Worker.Lfive_args_fast_path_range_\suffix: 1225*795d594fSAndroid Build Coastguard Worker ldr w5, [x8, #16] 1226*795d594fSAndroid Build Coastguard Worker.Lfour_args_fast_path_range_\suffix: 1227*795d594fSAndroid Build Coastguard Worker ldr w4, [x8, #12] 1228*795d594fSAndroid Build Coastguard Worker.Lthree_args_fast_path_range_\suffix: 1229*795d594fSAndroid Build Coastguard Worker ldr w3, [x8, #8] 1230*795d594fSAndroid Build Coastguard Worker.Ltwo_args_fast_path_range_\suffix: 1231*795d594fSAndroid Build Coastguard Worker ldr w2, [x8, #4] 1232*795d594fSAndroid Build Coastguard Worker.Lone_arg_fast_path_range_\suffix: 1233*795d594fSAndroid Build Coastguard Worker .if \is_static 1234*795d594fSAndroid Build Coastguard Worker ldr w1, [x8, #0] 1235*795d594fSAndroid Build Coastguard Worker .else 1236*795d594fSAndroid Build Coastguard Worker // First argument already in w1. 1237*795d594fSAndroid Build Coastguard Worker .endif 1238*795d594fSAndroid Build Coastguard Worker.Linvoke_fast_path_range_\suffix: 1239*795d594fSAndroid Build Coastguard Worker .if \is_interface 1240*795d594fSAndroid Build Coastguard Worker // Setup hidden argument. 1241*795d594fSAndroid Build Coastguard Worker mov ip2, x26 1242*795d594fSAndroid Build Coastguard Worker .endif 1243*795d594fSAndroid Build Coastguard Worker ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64] 1244*795d594fSAndroid Build Coastguard Worker blr lr 1245*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 3 1246*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 1247*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 1248*795d594fSAndroid Build Coastguard Worker 1249*795d594fSAndroid Build Coastguard Worker.Lfast_path_with_few_args_range_\suffix: 1250*795d594fSAndroid Build Coastguard Worker // Fast path when we have zero or one argument (modulo 'this'). If there 1251*795d594fSAndroid Build Coastguard Worker // is one argument, we can put it in both floating point and core register. 1252*795d594fSAndroid Build Coastguard Worker FETCH_B w2, 0, 1 // number of arguments 1253*795d594fSAndroid Build Coastguard Worker .if \is_static 1254*795d594fSAndroid Build Coastguard Worker cmp w2, #1 1255*795d594fSAndroid Build Coastguard Worker .else 1256*795d594fSAndroid Build Coastguard Worker cmp w2, #2 1257*795d594fSAndroid Build Coastguard Worker .endif 1258*795d594fSAndroid Build Coastguard Worker b.lt .Linvoke_with_few_args_range_\suffix 1259*795d594fSAndroid Build Coastguard Worker b.ne .Lget_shorty_range_\suffix 1260*795d594fSAndroid Build Coastguard Worker FETCH w3, 2 // dex register of first argument 1261*795d594fSAndroid Build Coastguard Worker .if \is_static 1262*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w3 1263*795d594fSAndroid Build Coastguard Worker fmov s0, w1 1264*795d594fSAndroid Build Coastguard Worker .else 1265*795d594fSAndroid Build Coastguard Worker add w3, w3, #1 // Add 1 for next argument 1266*795d594fSAndroid Build Coastguard Worker GET_VREG w2, w3 1267*795d594fSAndroid Build Coastguard Worker fmov s0, w2 1268*795d594fSAndroid Build Coastguard Worker .endif 1269*795d594fSAndroid Build Coastguard Worker.Linvoke_with_few_args_range_\suffix: 1270*795d594fSAndroid Build Coastguard Worker // Check if the next instruction is move-result or move-result-wide. 1271*795d594fSAndroid Build Coastguard Worker // If it is, we fetch the shorty and jump to the regular invocation. 1272*795d594fSAndroid Build Coastguard Worker FETCH w27, 3 1273*795d594fSAndroid Build Coastguard Worker and ip, x27, #0xfe 1274*795d594fSAndroid Build Coastguard Worker cmp ip, #0x0a 1275*795d594fSAndroid Build Coastguard Worker b.eq .Lget_shorty_and_invoke_range_\suffix 1276*795d594fSAndroid Build Coastguard Worker .if \is_interface 1277*795d594fSAndroid Build Coastguard Worker // Setup hidden argument. 1278*795d594fSAndroid Build Coastguard Worker mov ip2, x26 1279*795d594fSAndroid Build Coastguard Worker .endif 1280*795d594fSAndroid Build Coastguard Worker ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64] 1281*795d594fSAndroid Build Coastguard Worker blr lr 1282*795d594fSAndroid Build Coastguard Worker mov xINST, x27 1283*795d594fSAndroid Build Coastguard Worker ADVANCE 3 1284*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 1285*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 1286*795d594fSAndroid Build Coastguard Worker.Lget_shorty_and_invoke_range_\suffix: 1287*795d594fSAndroid Build Coastguard Worker GET_SHORTY_SLOW_PATH xINST, \is_interface 1288*795d594fSAndroid Build Coastguard Worker b .Lgpr_setup_finished_range_\suffix 1289*795d594fSAndroid Build Coastguard Worker .endif 1290*795d594fSAndroid Build Coastguard Worker 1291*795d594fSAndroid Build Coastguard Worker.Lget_shorty_range_\suffix: 1292*795d594fSAndroid Build Coastguard Worker GET_SHORTY xINST, \is_interface, \is_polymorphic, \is_custom 1293*795d594fSAndroid Build Coastguard Worker // From this point: 1294*795d594fSAndroid Build Coastguard Worker // - xINST contains shorty (in callee-save to switch over return value after call). 1295*795d594fSAndroid Build Coastguard Worker // - x0 contains method 1296*795d594fSAndroid Build Coastguard Worker // - x1 contains 'this' pointer for instance method. 1297*795d594fSAndroid Build Coastguard Worker // - for interface calls, x26 contains the interface method. 1298*795d594fSAndroid Build Coastguard Worker add x9, xINST, #1 // shorty + 1 ; ie skip return arg character 1299*795d594fSAndroid Build Coastguard Worker FETCH w10, 2 // arguments 1300*795d594fSAndroid Build Coastguard Worker .if \is_string_init 1301*795d594fSAndroid Build Coastguard Worker add x10, x10, #1 // arg start index 1302*795d594fSAndroid Build Coastguard Worker mov x11, #1 // index in stack 1303*795d594fSAndroid Build Coastguard Worker .elseif \is_static 1304*795d594fSAndroid Build Coastguard Worker mov x11, xzr // index in stack 1305*795d594fSAndroid Build Coastguard Worker .else 1306*795d594fSAndroid Build Coastguard Worker add x10, x10, #1 // arg start index 1307*795d594fSAndroid Build Coastguard Worker mov x11, #1 // index in stack 1308*795d594fSAndroid Build Coastguard Worker .endif 1309*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_FPS d0, s0, x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1310*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_FPS d1, s1, x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1311*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_FPS d2, s2, x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1312*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_FPS d3, s3, x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1313*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_FPS d4, s4, x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1314*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_FPS d5, s5, x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1315*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_FPS d6, s6, x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1316*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_FPS d7, s7, x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1317*795d594fSAndroid Build Coastguard Worker // Store in the outs array (stored above the ArtMethod in the stack) 1318*795d594fSAndroid Build Coastguard Worker add x11, x11, #2 // Add two words for the ArtMethod stored before the outs. 1319*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_FPs x9, w10, w11, .Lxmm_setup_finished_range_\suffix 1320*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished_range_\suffix: 1321*795d594fSAndroid Build Coastguard Worker add x9, xINST, #1 // shorty + 1 ; ie skip return arg character 1322*795d594fSAndroid Build Coastguard Worker FETCH w10, 2 // arguments 1323*795d594fSAndroid Build Coastguard Worker .if \is_string_init 1324*795d594fSAndroid Build Coastguard Worker add x10, x10, #1 // arg start index 1325*795d594fSAndroid Build Coastguard Worker mov x11, #1 // index in stack 1326*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x1, w1, x9, w10, w11, .Lgpr_setup_finished_range_\suffix 1327*795d594fSAndroid Build Coastguard Worker .elseif \is_static 1328*795d594fSAndroid Build Coastguard Worker mov x11, xzr // index in stack 1329*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x1, w1, x9, w10, w11 .Lgpr_setup_finished_range_\suffix 1330*795d594fSAndroid Build Coastguard Worker .else 1331*795d594fSAndroid Build Coastguard Worker add x10, x10, #1 // arg start index 1332*795d594fSAndroid Build Coastguard Worker mov x11, #1 // index in stack 1333*795d594fSAndroid Build Coastguard Worker .endif 1334*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x2, w2, x9, w10, w11, .Lgpr_setup_finished_range_\suffix 1335*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x3, w3, x9, w10, w11, .Lgpr_setup_finished_range_\suffix 1336*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x4, w4, x9, w10, w11, .Lgpr_setup_finished_range_\suffix 1337*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x5, w5, x9, w10, w11, .Lgpr_setup_finished_range_\suffix 1338*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x6, w6, x9, w10, w11, .Lgpr_setup_finished_range_\suffix 1339*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_SHORTY_LOADING_GPRS x7, w7, x9, w10, w11, .Lgpr_setup_finished_range_\suffix 1340*795d594fSAndroid Build Coastguard Worker // Store in the outs array (stored above the ArtMethod in the stack) 1341*795d594fSAndroid Build Coastguard Worker add x11, x11, #2 // Add two words for the ArtMethod stored before the outs. 1342*795d594fSAndroid Build Coastguard Worker LOOP_RANGE_OVER_INTs x9, w10, w11, .Lgpr_setup_finished_range_\suffix 1343*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished_range_\suffix: 1344*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 1345*795d594fSAndroid Build Coastguard Worker bl art_quick_invoke_polymorphic 1346*795d594fSAndroid Build Coastguard Worker .elseif \is_custom 1347*795d594fSAndroid Build Coastguard Worker bl art_quick_invoke_custom 1348*795d594fSAndroid Build Coastguard Worker .else 1349*795d594fSAndroid Build Coastguard Worker .if \is_interface 1350*795d594fSAndroid Build Coastguard Worker // Setup hidden argument. 1351*795d594fSAndroid Build Coastguard Worker mov ip2, x26 1352*795d594fSAndroid Build Coastguard Worker .endif 1353*795d594fSAndroid Build Coastguard Worker ldr lr, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64] 1354*795d594fSAndroid Build Coastguard Worker blr lr 1355*795d594fSAndroid Build Coastguard Worker .endif 1356*795d594fSAndroid Build Coastguard Worker SETUP_RETURN_VALUE xINST 1357*795d594fSAndroid Build Coastguard Worker.Ldone_return_range_\suffix: 1358*795d594fSAndroid Build Coastguard Worker /* resume execution of caller */ 1359*795d594fSAndroid Build Coastguard Worker .if \is_string_init 1360*795d594fSAndroid Build Coastguard Worker FETCH w11, 2 // arguments 1361*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w11 1362*795d594fSAndroid Build Coastguard Worker UPDATE_REGISTERS_FOR_STRING_INIT w1, w0 1363*795d594fSAndroid Build Coastguard Worker .endif 1364*795d594fSAndroid Build Coastguard Worker 1365*795d594fSAndroid Build Coastguard Worker .if \is_polymorphic 1366*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 4 1367*795d594fSAndroid Build Coastguard Worker .else 1368*795d594fSAndroid Build Coastguard Worker FETCH_ADVANCE_INST 3 1369*795d594fSAndroid Build Coastguard Worker .endif 1370*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 1371*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 1372*795d594fSAndroid Build Coastguard Worker.endm 1373*795d594fSAndroid Build Coastguard Worker 1374*795d594fSAndroid Build Coastguard Worker.macro POISON_HEAP_REF_IF_OBJECT is_object, rRef 1375*795d594fSAndroid Build Coastguard Worker .if \is_object 1376*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF \rRef 1377*795d594fSAndroid Build Coastguard Worker .endif 1378*795d594fSAndroid Build Coastguard Worker.endm 1379*795d594fSAndroid Build Coastguard Worker 1380*795d594fSAndroid Build Coastguard Worker.macro WRITE_BARRIER_IF_OBJECT is_object, value, holder, label 1381*795d594fSAndroid Build Coastguard Worker .if \is_object 1382*795d594fSAndroid Build Coastguard Worker cbz \value, \label 1383*795d594fSAndroid Build Coastguard Worker ldr ip, [xSELF, #THREAD_CARD_TABLE_OFFSET] 1384*795d594fSAndroid Build Coastguard Worker lsr wip2, \holder, #CARD_TABLE_CARD_SHIFT 1385*795d594fSAndroid Build Coastguard Worker strb wip, [ip, ip2] 1386*795d594fSAndroid Build Coastguard Worker\label: 1387*795d594fSAndroid Build Coastguard Worker .endif 1388*795d594fSAndroid Build Coastguard Worker.endm 1389*795d594fSAndroid Build Coastguard Worker 1390*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object parameter passed in physical register 1391*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry, and in case of object in the 1392*795d594fSAndroid Build Coastguard Worker// expected reference array entry. 1393*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_STORING_GPRS gpr_64, gpr_32, shorty, arg_offset, regs, refs, finished 1394*795d594fSAndroid Build Coastguard Worker1: // LOOP 1395*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 1396*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 1397*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip == 'J') goto FOUND_LONG 1398*795d594fSAndroid Build Coastguard Worker b.eq 2f 1399*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto SKIP_FLOAT 1400*795d594fSAndroid Build Coastguard Worker b.eq 3f 1401*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto SKIP_DOUBLE 1402*795d594fSAndroid Build Coastguard Worker b.eq 4f 1403*795d594fSAndroid Build Coastguard Worker str \gpr_32, [\regs, \arg_offset] 1404*795d594fSAndroid Build Coastguard Worker cmp wip, #76 // if (wip != 'L') goto NOT_REFERENCE 1405*795d594fSAndroid Build Coastguard Worker b.ne 6f 1406*795d594fSAndroid Build Coastguard Worker str \gpr_32, [\refs, \arg_offset] 1407*795d594fSAndroid Build Coastguard Worker6: // NOT_REFERENCE 1408*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1409*795d594fSAndroid Build Coastguard Worker b 5f 1410*795d594fSAndroid Build Coastguard Worker2: // FOUND_LONG 1411*795d594fSAndroid Build Coastguard Worker str \gpr_64, [\regs, \arg_offset] 1412*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #8 1413*795d594fSAndroid Build Coastguard Worker b 5f 1414*795d594fSAndroid Build Coastguard Worker3: // SKIP_FLOAT 1415*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1416*795d594fSAndroid Build Coastguard Worker b 1b 1417*795d594fSAndroid Build Coastguard Worker4: // SKIP_DOUBLE 1418*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #8 1419*795d594fSAndroid Build Coastguard Worker b 1b 1420*795d594fSAndroid Build Coastguard Worker5: 1421*795d594fSAndroid Build Coastguard Worker.endm 1422*795d594fSAndroid Build Coastguard Worker 1423*795d594fSAndroid Build Coastguard Worker// Puts the next floating point parameter passed in physical register 1424*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry. 1425*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary. 1426*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_SHORTY_STORING_FPS dreg, sreg, shorty, arg_offset, fp, finished 1427*795d594fSAndroid Build Coastguard Worker1: // LOOP 1428*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 1429*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 1430*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto FOUND_DOUBLE 1431*795d594fSAndroid Build Coastguard Worker b.eq 2f 1432*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto FOUND_FLOAT 1433*795d594fSAndroid Build Coastguard Worker b.eq 3f 1434*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1435*795d594fSAndroid Build Coastguard Worker // Handle extra argument in arg array taken by a long. 1436*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip != 'J') goto LOOP 1437*795d594fSAndroid Build Coastguard Worker b.ne 1b 1438*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1439*795d594fSAndroid Build Coastguard Worker b 1b // goto LOOP 1440*795d594fSAndroid Build Coastguard Worker2: // FOUND_DOUBLE 1441*795d594fSAndroid Build Coastguard Worker str \dreg, [\fp, \arg_offset] 1442*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #8 1443*795d594fSAndroid Build Coastguard Worker b 4f 1444*795d594fSAndroid Build Coastguard Worker3: // FOUND_FLOAT 1445*795d594fSAndroid Build Coastguard Worker str \sreg, [\fp, \arg_offset] 1446*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1447*795d594fSAndroid Build Coastguard Worker4: 1448*795d594fSAndroid Build Coastguard Worker.endm 1449*795d594fSAndroid Build Coastguard Worker 1450*795d594fSAndroid Build Coastguard Worker// Puts the next floating point parameter passed in stack 1451*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry. 1452*795d594fSAndroid Build Coastguard Worker// Uses ip as temporary. 1453*795d594fSAndroid Build Coastguard Worker// 1454*795d594fSAndroid Build Coastguard Worker// TODO: Or we could just spill regs to the reserved slots in the caller's 1455*795d594fSAndroid Build Coastguard Worker// frame and copy all regs in a simple loop. This time, however, we would 1456*795d594fSAndroid Build Coastguard Worker// need to look at the shorty anyway to look for the references. 1457*795d594fSAndroid Build Coastguard Worker// (The trade-off is different for passing arguments and receiving them.) 1458*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_FPs shorty, arg_offset, regs, stack_ptr, finished 1459*795d594fSAndroid Build Coastguard Worker1: // LOOP 1460*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 1461*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 1462*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto FOUND_DOUBLE 1463*795d594fSAndroid Build Coastguard Worker b.eq 2f 1464*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto FOUND_FLOAT 1465*795d594fSAndroid Build Coastguard Worker b.eq 3f 1466*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1467*795d594fSAndroid Build Coastguard Worker // Handle extra argument in arg array taken by a long. 1468*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip != 'J') goto LOOP 1469*795d594fSAndroid Build Coastguard Worker b.ne 1b 1470*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1471*795d594fSAndroid Build Coastguard Worker b 1b // goto LOOP 1472*795d594fSAndroid Build Coastguard Worker2: // FOUND_DOUBLE 1473*795d594fSAndroid Build Coastguard Worker add ip, \stack_ptr, \arg_offset 1474*795d594fSAndroid Build Coastguard Worker ldr ip, [ip, #OFFSET_TO_FIRST_ARGUMENT_IN_STACK] 1475*795d594fSAndroid Build Coastguard Worker str ip, [\regs, \arg_offset] 1476*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #8 1477*795d594fSAndroid Build Coastguard Worker b 1b 1478*795d594fSAndroid Build Coastguard Worker3: // FOUND_FLOAT 1479*795d594fSAndroid Build Coastguard Worker add ip, \stack_ptr, \arg_offset 1480*795d594fSAndroid Build Coastguard Worker ldr wip, [ip, #OFFSET_TO_FIRST_ARGUMENT_IN_STACK] 1481*795d594fSAndroid Build Coastguard Worker str wip, [\regs, \arg_offset] 1482*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1483*795d594fSAndroid Build Coastguard Worker b 1b 1484*795d594fSAndroid Build Coastguard Worker.endm 1485*795d594fSAndroid Build Coastguard Worker 1486*795d594fSAndroid Build Coastguard Worker// Puts the next int/long/object parameter passed in stack 1487*795d594fSAndroid Build Coastguard Worker// in the expected dex register array entry, and in case of object in the 1488*795d594fSAndroid Build Coastguard Worker// expected reference array entry. 1489*795d594fSAndroid Build Coastguard Worker// Uses ip and ip2 as temporary. 1490*795d594fSAndroid Build Coastguard Worker.macro LOOP_OVER_INTs shorty, arg_offset, regs, refs, stack_ptr, finished 1491*795d594fSAndroid Build Coastguard Worker1: // LOOP 1492*795d594fSAndroid Build Coastguard Worker ldrb wip, [\shorty], #1 // Load next character in shorty, and increment. 1493*795d594fSAndroid Build Coastguard Worker cbz wip, \finished // if (wip == '\0') goto finished 1494*795d594fSAndroid Build Coastguard Worker cmp wip, #74 // if (wip == 'J') goto FOUND_LONG 1495*795d594fSAndroid Build Coastguard Worker b.eq 2f 1496*795d594fSAndroid Build Coastguard Worker cmp wip, #70 // if (wip == 'F') goto SKIP_FLOAT 1497*795d594fSAndroid Build Coastguard Worker b.eq 3f 1498*795d594fSAndroid Build Coastguard Worker cmp wip, #68 // if (wip == 'D') goto SKIP_DOUBLE 1499*795d594fSAndroid Build Coastguard Worker b.eq 4f 1500*795d594fSAndroid Build Coastguard Worker add ip2, \stack_ptr, \arg_offset 1501*795d594fSAndroid Build Coastguard Worker ldr wip2, [ip2, #OFFSET_TO_FIRST_ARGUMENT_IN_STACK] 1502*795d594fSAndroid Build Coastguard Worker str wip2, [\regs, \arg_offset] 1503*795d594fSAndroid Build Coastguard Worker cmp wip, #76 // if (wip != 'L') goto loop 1504*795d594fSAndroid Build Coastguard Worker b.ne 3f 1505*795d594fSAndroid Build Coastguard Worker str wip2, [\refs, \arg_offset] 1506*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1507*795d594fSAndroid Build Coastguard Worker b 1b 1508*795d594fSAndroid Build Coastguard Worker2: // FOUND_LONG 1509*795d594fSAndroid Build Coastguard Worker add ip, \stack_ptr, \arg_offset 1510*795d594fSAndroid Build Coastguard Worker ldr ip, [ip, #OFFSET_TO_FIRST_ARGUMENT_IN_STACK] 1511*795d594fSAndroid Build Coastguard Worker str ip, [\regs, \arg_offset] 1512*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #8 1513*795d594fSAndroid Build Coastguard Worker b 1b 1514*795d594fSAndroid Build Coastguard Worker3: // SKIP_FLOAT 1515*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1516*795d594fSAndroid Build Coastguard Worker b 1b 1517*795d594fSAndroid Build Coastguard Worker4: // SKIP_DOUBLE 1518*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #8 1519*795d594fSAndroid Build Coastguard Worker b 1b 1520*795d594fSAndroid Build Coastguard Worker.endm 1521*795d594fSAndroid Build Coastguard Worker 1522*795d594fSAndroid Build Coastguard Worker.macro SETUP_REFERENCE_PARAMETER_IN_GPR gpr32, regs, refs, ins, arg_offset, finished 1523*795d594fSAndroid Build Coastguard Worker str \gpr32, [\regs, \arg_offset] 1524*795d594fSAndroid Build Coastguard Worker sub \ins, \ins, #1 1525*795d594fSAndroid Build Coastguard Worker str \gpr32, [\refs, \arg_offset] 1526*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1527*795d594fSAndroid Build Coastguard Worker cbz \ins, \finished 1528*795d594fSAndroid Build Coastguard Worker.endm 1529*795d594fSAndroid Build Coastguard Worker 1530*795d594fSAndroid Build Coastguard Worker// Uses ip2 as temporary. 1531*795d594fSAndroid Build Coastguard Worker.macro SETUP_REFERENCE_PARAMETERS_IN_STACK regs, refs, ins, stack_ptr, arg_offset 1532*795d594fSAndroid Build Coastguard Worker1: 1533*795d594fSAndroid Build Coastguard Worker ldr wip2, [\stack_ptr, \arg_offset] 1534*795d594fSAndroid Build Coastguard Worker sub \ins, \ins, #1 1535*795d594fSAndroid Build Coastguard Worker str wip2, [\regs, \arg_offset] 1536*795d594fSAndroid Build Coastguard Worker str wip2, [\refs, \arg_offset] 1537*795d594fSAndroid Build Coastguard Worker add \arg_offset, \arg_offset, #4 1538*795d594fSAndroid Build Coastguard Worker cbnz \ins, 1b 1539*795d594fSAndroid Build Coastguard Worker.endm 1540*795d594fSAndroid Build Coastguard Worker 1541*795d594fSAndroid Build Coastguard Worker.macro CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot, if_not_hot 1542*795d594fSAndroid Build Coastguard Worker ldr wip, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET] 1543*795d594fSAndroid Build Coastguard Worker tbz wip, #ART_METHOD_IS_MEMORY_SHARED_FLAG_BIT, \if_hot 1544*795d594fSAndroid Build Coastguard Worker // Intrinsics are always in the boot image and considered hot. 1545*795d594fSAndroid Build Coastguard Worker tbnz wip, #ART_METHOD_IS_INTRINSIC_FLAG_BIT, \if_hot 1546*795d594fSAndroid Build Coastguard Worker ldr wip, [xSELF, #THREAD_SHARED_METHOD_HOTNESS_OFFSET] 1547*795d594fSAndroid Build Coastguard Worker cbz wip, \if_hot 1548*795d594fSAndroid Build Coastguard Worker add wip, wip, #-1 1549*795d594fSAndroid Build Coastguard Worker str wip, [xSELF, #THREAD_SHARED_METHOD_HOTNESS_OFFSET] 1550*795d594fSAndroid Build Coastguard Worker b \if_not_hot 1551*795d594fSAndroid Build Coastguard Worker.endm 1552*795d594fSAndroid Build Coastguard Worker 1553*795d594fSAndroid Build Coastguard Worker.macro DO_SUSPEND_CHECK continue_label 1554*795d594fSAndroid Build Coastguard Worker ldr wip, [xSELF, #THREAD_FLAGS_OFFSET] 1555*795d594fSAndroid Build Coastguard Worker tst wip, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST 1556*795d594fSAndroid Build Coastguard Worker b.eq \continue_label 1557*795d594fSAndroid Build Coastguard Worker EXPORT_PC 1558*795d594fSAndroid Build Coastguard Worker bl art_quick_test_suspend 1559*795d594fSAndroid Build Coastguard Worker.endm 1560*795d594fSAndroid Build Coastguard Worker 1561*795d594fSAndroid Build Coastguard Worker%def entry(): 1562*795d594fSAndroid Build Coastguard Worker/* 1563*795d594fSAndroid Build Coastguard Worker * ArtMethod entry point. 1564*795d594fSAndroid Build Coastguard Worker * 1565*795d594fSAndroid Build Coastguard Worker * On entry: 1566*795d594fSAndroid Build Coastguard Worker * x0 ArtMethod* callee 1567*795d594fSAndroid Build Coastguard Worker * rest method parameters 1568*795d594fSAndroid Build Coastguard Worker */ 1569*795d594fSAndroid Build Coastguard Worker 1570*795d594fSAndroid Build Coastguard WorkerOAT_ENTRY ExecuteNterpWithClinitImpl 1571*795d594fSAndroid Build Coastguard Worker .cfi_startproc 1572*795d594fSAndroid Build Coastguard Worker // For simplicity, we don't do a read barrier here, but instead rely 1573*795d594fSAndroid Build Coastguard Worker // on art_quick_resolution_trampoline to always have a suspend point before 1574*795d594fSAndroid Build Coastguard Worker // calling back here. 1575*795d594fSAndroid Build Coastguard Worker ldr wip, [x0, #ART_METHOD_DECLARING_CLASS_OFFSET] 1576*795d594fSAndroid Build Coastguard Worker ldr wip2, [ip, #MIRROR_CLASS_STATUS_OFFSET] 1577*795d594fSAndroid Build Coastguard Worker lsr wip2, wip2, #MIRROR_CLASS_STATUS_SHIFT 1578*795d594fSAndroid Build Coastguard Worker cmp wip2, #MIRROR_CLASS_STATUS_VISIBLY_INITIALIZED 1579*795d594fSAndroid Build Coastguard Worker b.hs ExecuteNterpImpl 1580*795d594fSAndroid Build Coastguard Worker cmp wip2, #MIRROR_CLASS_STATUS_INITIALIZED 1581*795d594fSAndroid Build Coastguard Worker b.lo .Linitializing_check 1582*795d594fSAndroid Build Coastguard Worker dmb ish 1583*795d594fSAndroid Build Coastguard Worker b ExecuteNterpImpl 1584*795d594fSAndroid Build Coastguard Worker.Linitializing_check: 1585*795d594fSAndroid Build Coastguard Worker cmp wip2, #MIRROR_CLASS_STATUS_INITIALIZING 1586*795d594fSAndroid Build Coastguard Worker b.lo .Lresolution_trampoline 1587*795d594fSAndroid Build Coastguard Worker ldr wip2, [ip, #MIRROR_CLASS_CLINIT_THREAD_ID_OFFSET] 1588*795d594fSAndroid Build Coastguard Worker ldr wip, [xSELF, #THREAD_TID_OFFSET] 1589*795d594fSAndroid Build Coastguard Worker cmp wip, wip2 1590*795d594fSAndroid Build Coastguard Worker b.eq ExecuteNterpImpl 1591*795d594fSAndroid Build Coastguard Worker.Lresolution_trampoline: 1592*795d594fSAndroid Build Coastguard Worker b art_quick_resolution_trampoline 1593*795d594fSAndroid Build Coastguard Worker .cfi_endproc 1594*795d594fSAndroid Build Coastguard Worker .type EndExecuteNterpWithClinitImpl, #function 1595*795d594fSAndroid Build Coastguard Worker .hidden EndExecuteNterpWithClinitImpl 1596*795d594fSAndroid Build Coastguard Worker .global EndExecuteNterpWithClinitImpl 1597*795d594fSAndroid Build Coastguard WorkerEndExecuteNterpWithClinitImpl: 1598*795d594fSAndroid Build Coastguard Worker 1599*795d594fSAndroid Build Coastguard WorkerOAT_ENTRY ExecuteNterpImpl 1600*795d594fSAndroid Build Coastguard Worker .cfi_startproc 1601*795d594fSAndroid Build Coastguard Worker sub x16, sp, #STACK_OVERFLOW_RESERVED_BYTES 1602*795d594fSAndroid Build Coastguard Worker ldr wzr, [x16] 1603*795d594fSAndroid Build Coastguard Worker /* Spill callee save regs */ 1604*795d594fSAndroid Build Coastguard Worker SPILL_ALL_CALLEE_SAVES 1605*795d594fSAndroid Build Coastguard Worker 1606*795d594fSAndroid Build Coastguard Worker ldr xPC, [x0, #ART_METHOD_DATA_OFFSET_64] 1607*795d594fSAndroid Build Coastguard Worker // Setup the stack for executing the method. 1608*795d594fSAndroid Build Coastguard Worker SETUP_STACK_FRAME xPC, xREFS, xFP, CFI_REFS, load_ins=1 1609*795d594fSAndroid Build Coastguard Worker 1610*795d594fSAndroid Build Coastguard Worker // Setup the parameters 1611*795d594fSAndroid Build Coastguard Worker cbz w15, .Lxmm_setup_finished 1612*795d594fSAndroid Build Coastguard Worker 1613*795d594fSAndroid Build Coastguard Worker sub ip2, ip, x15 1614*795d594fSAndroid Build Coastguard Worker ldr w26, [x0, #ART_METHOD_ACCESS_FLAGS_OFFSET] 1615*795d594fSAndroid Build Coastguard Worker lsl x27, ip2, #2 // x27 is now the offset for inputs into the registers array. 1616*795d594fSAndroid Build Coastguard Worker 1617*795d594fSAndroid Build Coastguard Worker tbz w26, #ART_METHOD_NTERP_ENTRY_POINT_FAST_PATH_FLAG_BIT, .Lsetup_slow_path 1618*795d594fSAndroid Build Coastguard Worker // Setup pointer to inputs in FP and pointer to inputs in REFS 1619*795d594fSAndroid Build Coastguard Worker add x10, xFP, x27 1620*795d594fSAndroid Build Coastguard Worker add x11, xREFS, x27 1621*795d594fSAndroid Build Coastguard Worker mov x12, #0 1622*795d594fSAndroid Build Coastguard Worker SETUP_REFERENCE_PARAMETER_IN_GPR w1, x10, x11, w15, x12, .Lxmm_setup_finished 1623*795d594fSAndroid Build Coastguard Worker SETUP_REFERENCE_PARAMETER_IN_GPR w2, x10, x11, w15, x12, .Lxmm_setup_finished 1624*795d594fSAndroid Build Coastguard Worker SETUP_REFERENCE_PARAMETER_IN_GPR w3, x10, x11, w15, x12, .Lxmm_setup_finished 1625*795d594fSAndroid Build Coastguard Worker SETUP_REFERENCE_PARAMETER_IN_GPR w4, x10, x11, w15, x12, .Lxmm_setup_finished 1626*795d594fSAndroid Build Coastguard Worker SETUP_REFERENCE_PARAMETER_IN_GPR w5, x10, x11, w15, x12, .Lxmm_setup_finished 1627*795d594fSAndroid Build Coastguard Worker SETUP_REFERENCE_PARAMETER_IN_GPR w6, x10, x11, w15, x12, .Lxmm_setup_finished 1628*795d594fSAndroid Build Coastguard Worker SETUP_REFERENCE_PARAMETER_IN_GPR w7, x10, x11, w15, x12, .Lxmm_setup_finished 1629*795d594fSAndroid Build Coastguard Worker add x28, x28, #OFFSET_TO_FIRST_ARGUMENT_IN_STACK 1630*795d594fSAndroid Build Coastguard Worker SETUP_REFERENCE_PARAMETERS_IN_STACK x10, x11, w15, x28, x12 1631*795d594fSAndroid Build Coastguard Worker b .Lxmm_setup_finished 1632*795d594fSAndroid Build Coastguard Worker 1633*795d594fSAndroid Build Coastguard Worker.Lsetup_slow_path: 1634*795d594fSAndroid Build Coastguard Worker // If the method is not static and there is one argument ('this'), we don't need to fetch the 1635*795d594fSAndroid Build Coastguard Worker // shorty. 1636*795d594fSAndroid Build Coastguard Worker tbnz w26, #ART_METHOD_IS_STATIC_FLAG_BIT, .Lsetup_with_shorty 1637*795d594fSAndroid Build Coastguard Worker str w1, [xFP, x27] 1638*795d594fSAndroid Build Coastguard Worker str w1, [xREFS, x27] 1639*795d594fSAndroid Build Coastguard Worker cmp w15, #1 1640*795d594fSAndroid Build Coastguard Worker b.eq .Lxmm_setup_finished 1641*795d594fSAndroid Build Coastguard Worker 1642*795d594fSAndroid Build Coastguard Worker.Lsetup_with_shorty: 1643*795d594fSAndroid Build Coastguard Worker // TODO: Get shorty in a better way and remove below 1644*795d594fSAndroid Build Coastguard Worker SPILL_ALL_ARGUMENTS 1645*795d594fSAndroid Build Coastguard Worker bl NterpGetShorty 1646*795d594fSAndroid Build Coastguard Worker // Save shorty in callee-save xIBASE. 1647*795d594fSAndroid Build Coastguard Worker mov xIBASE, x0 1648*795d594fSAndroid Build Coastguard Worker RESTORE_ALL_ARGUMENTS 1649*795d594fSAndroid Build Coastguard Worker 1650*795d594fSAndroid Build Coastguard Worker // Setup pointer to inputs in FP and pointer to inputs in REFS 1651*795d594fSAndroid Build Coastguard Worker add x10, xFP, x27 1652*795d594fSAndroid Build Coastguard Worker add x11, xREFS, x27 1653*795d594fSAndroid Build Coastguard Worker mov x12, #0 1654*795d594fSAndroid Build Coastguard Worker 1655*795d594fSAndroid Build Coastguard Worker add x9, xIBASE, #1 // shorty + 1 ; ie skip return arg character 1656*795d594fSAndroid Build Coastguard Worker tbnz w26, #ART_METHOD_IS_STATIC_FLAG_BIT, .Lhandle_static_method 1657*795d594fSAndroid Build Coastguard Worker add x10, x10, #4 1658*795d594fSAndroid Build Coastguard Worker add x11, x11, #4 1659*795d594fSAndroid Build Coastguard Worker add x28, x28, #4 1660*795d594fSAndroid Build Coastguard Worker b .Lcontinue_setup_gprs 1661*795d594fSAndroid Build Coastguard Worker.Lhandle_static_method: 1662*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_GPRS x1, w1, x9, x12, x10, x11, .Lgpr_setup_finished 1663*795d594fSAndroid Build Coastguard Worker.Lcontinue_setup_gprs: 1664*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_GPRS x2, w2, x9, x12, x10, x11, .Lgpr_setup_finished 1665*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_GPRS x3, w3, x9, x12, x10, x11, .Lgpr_setup_finished 1666*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_GPRS x4, w4, x9, x12, x10, x11, .Lgpr_setup_finished 1667*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_GPRS x5, w5, x9, x12, x10, x11, .Lgpr_setup_finished 1668*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_GPRS x6, w6, x9, x12, x10, x11, .Lgpr_setup_finished 1669*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_GPRS x7, w7, x9, x12, x10, x11, .Lgpr_setup_finished 1670*795d594fSAndroid Build Coastguard Worker LOOP_OVER_INTs x9, x12, x10, x11, x28, .Lgpr_setup_finished 1671*795d594fSAndroid Build Coastguard Worker.Lgpr_setup_finished: 1672*795d594fSAndroid Build Coastguard Worker add x9, xIBASE, #1 // shorty + 1 ; ie skip return arg character 1673*795d594fSAndroid Build Coastguard Worker mov x12, #0 // reset counter 1674*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_FPS d0, s0, x9, x12, x10, .Lxmm_setup_finished 1675*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_FPS d1, s1, x9, x12, x10, .Lxmm_setup_finished 1676*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_FPS d2, s2, x9, x12, x10, .Lxmm_setup_finished 1677*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_FPS d3, s3, x9, x12, x10, .Lxmm_setup_finished 1678*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_FPS d4, s4, x9, x12, x10, .Lxmm_setup_finished 1679*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_FPS d5, s5, x9, x12, x10, .Lxmm_setup_finished 1680*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_FPS d6, s6, x9, x12, x10, .Lxmm_setup_finished 1681*795d594fSAndroid Build Coastguard Worker LOOP_OVER_SHORTY_STORING_FPS d7, s7, x9, x12, x10, .Lxmm_setup_finished 1682*795d594fSAndroid Build Coastguard Worker LOOP_OVER_FPs x9, x12, x10, x28, .Lxmm_setup_finished 1683*795d594fSAndroid Build Coastguard Worker.Lxmm_setup_finished: 1684*795d594fSAndroid Build Coastguard Worker CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0) 1685*795d594fSAndroid Build Coastguard Worker 1686*795d594fSAndroid Build Coastguard Worker // Set rIBASE 1687*795d594fSAndroid Build Coastguard Worker adr xIBASE, artNterpAsmInstructionStart 1688*795d594fSAndroid Build Coastguard Worker /* start executing the instruction at xPC */ 1689*795d594fSAndroid Build Coastguard Worker START_EXECUTING_INSTRUCTIONS 1690*795d594fSAndroid Build Coastguard Worker /* NOTE: no fallthrough */ 1691*795d594fSAndroid Build Coastguard Worker // cfi info continues, and covers the whole nterp implementation. 1692*795d594fSAndroid Build Coastguard Worker SIZE ExecuteNterpImpl 1693*795d594fSAndroid Build Coastguard Worker 1694*795d594fSAndroid Build Coastguard Worker%def opcode_pre(): 1695*795d594fSAndroid Build Coastguard Worker 1696*795d594fSAndroid Build Coastguard Worker%def fetch_from_thread_cache(dest_reg, miss_label): 1697*795d594fSAndroid Build Coastguard Worker // Fetch some information from the thread cache. 1698*795d594fSAndroid Build Coastguard Worker // Uses ip and ip2 as temporaries. 1699*795d594fSAndroid Build Coastguard Worker add ip, xSELF, #THREAD_INTERPRETER_CACHE_OFFSET // cache address 1700*795d594fSAndroid Build Coastguard Worker ubfx ip2, xPC, #2, #THREAD_INTERPRETER_CACHE_SIZE_LOG2 // entry index 1701*795d594fSAndroid Build Coastguard Worker add ip, ip, ip2, lsl #4 // entry address within the cache 1702*795d594fSAndroid Build Coastguard Worker ldp ip, ${dest_reg}, [ip] // entry key (pc) and value (offset) 1703*795d594fSAndroid Build Coastguard Worker cmp ip, xPC 1704*795d594fSAndroid Build Coastguard Worker b.ne ${miss_label} 1705*795d594fSAndroid Build Coastguard Worker 1706*795d594fSAndroid Build Coastguard Worker%def footer(): 1707*795d594fSAndroid Build Coastguard Worker/* 1708*795d594fSAndroid Build Coastguard Worker * =========================================================================== 1709*795d594fSAndroid Build Coastguard Worker * Common subroutines and data 1710*795d594fSAndroid Build Coastguard Worker * =========================================================================== 1711*795d594fSAndroid Build Coastguard Worker */ 1712*795d594fSAndroid Build Coastguard Worker 1713*795d594fSAndroid Build Coastguard Worker .text 1714*795d594fSAndroid Build Coastguard Worker .align 2 1715*795d594fSAndroid Build Coastguard Worker 1716*795d594fSAndroid Build Coastguard Worker// Enclose all code below in a symbol (which gets printed in backtraces). 1717*795d594fSAndroid Build Coastguard WorkerNAME_START nterp_helper 1718*795d594fSAndroid Build Coastguard Worker 1719*795d594fSAndroid Build Coastguard Worker// Note: mterp also uses the common_* names below for helpers, but that's OK 1720*795d594fSAndroid Build Coastguard Worker// as the assembler compiled each interpreter separately. 1721*795d594fSAndroid Build Coastguard Workercommon_errDivideByZero: 1722*795d594fSAndroid Build Coastguard Worker EXPORT_PC 1723*795d594fSAndroid Build Coastguard Worker bl art_quick_throw_div_zero 1724*795d594fSAndroid Build Coastguard Worker 1725*795d594fSAndroid Build Coastguard Worker// Expect index in w1, length in w3. 1726*795d594fSAndroid Build Coastguard Workercommon_errArrayIndex: 1727*795d594fSAndroid Build Coastguard Worker EXPORT_PC 1728*795d594fSAndroid Build Coastguard Worker mov x0, x1 1729*795d594fSAndroid Build Coastguard Worker mov x1, x3 1730*795d594fSAndroid Build Coastguard Worker bl art_quick_throw_array_bounds 1731*795d594fSAndroid Build Coastguard Worker 1732*795d594fSAndroid Build Coastguard Workercommon_errNullObject: 1733*795d594fSAndroid Build Coastguard Worker EXPORT_PC 1734*795d594fSAndroid Build Coastguard Worker bl art_quick_throw_null_pointer_exception 1735*795d594fSAndroid Build Coastguard Worker 1736*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeStatic: 1737*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_NON_RANGE is_static=1, suffix="invokeStatic" 1738*795d594fSAndroid Build Coastguard Worker 1739*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeStaticRange: 1740*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_RANGE is_static=1, suffix="invokeStatic" 1741*795d594fSAndroid Build Coastguard Worker 1742*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInstance: 1743*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_NON_RANGE suffix="invokeInstance" 1744*795d594fSAndroid Build Coastguard Worker 1745*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInstanceRange: 1746*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_RANGE suffix="invokeInstance" 1747*795d594fSAndroid Build Coastguard Worker 1748*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInterface: 1749*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_NON_RANGE is_interface=1, suffix="invokeInterface" 1750*795d594fSAndroid Build Coastguard Worker 1751*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeInterfaceRange: 1752*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_RANGE is_interface=1, suffix="invokeInterface" 1753*795d594fSAndroid Build Coastguard Worker 1754*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokePolymorphic: 1755*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_NON_RANGE is_polymorphic=1, suffix="invokePolymorphic" 1756*795d594fSAndroid Build Coastguard Worker 1757*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokePolymorphicRange: 1758*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_RANGE is_polymorphic=1, suffix="invokePolymorphic" 1759*795d594fSAndroid Build Coastguard Worker 1760*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeCustom: 1761*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_NON_RANGE is_static=1, is_custom=1, suffix="invokeCustom" 1762*795d594fSAndroid Build Coastguard Worker 1763*795d594fSAndroid Build Coastguard WorkerNterpCommonInvokeCustomRange: 1764*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_RANGE is_static=1, is_custom=1, suffix="invokeCustom" 1765*795d594fSAndroid Build Coastguard Worker 1766*795d594fSAndroid Build Coastguard WorkerNterpHandleStringInit: 1767*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_NON_RANGE is_string_init=1, suffix="stringInit" 1768*795d594fSAndroid Build Coastguard Worker 1769*795d594fSAndroid Build Coastguard WorkerNterpHandleStringInitRange: 1770*795d594fSAndroid Build Coastguard Worker COMMON_INVOKE_RANGE is_string_init=1, suffix="stringInit" 1771*795d594fSAndroid Build Coastguard Worker 1772*795d594fSAndroid Build Coastguard WorkerNterpHandleHotnessOverflow: 1773*795d594fSAndroid Build Coastguard Worker CHECK_AND_UPDATE_SHARED_MEMORY_METHOD if_hot=1f, if_not_hot=5f 1774*795d594fSAndroid Build Coastguard Worker1: 1775*795d594fSAndroid Build Coastguard Worker mov x1, xPC 1776*795d594fSAndroid Build Coastguard Worker mov x2, xFP 1777*795d594fSAndroid Build Coastguard Worker bl nterp_hot_method 1778*795d594fSAndroid Build Coastguard Worker cbnz x0, 3f 1779*795d594fSAndroid Build Coastguard Worker2: 1780*795d594fSAndroid Build Coastguard Worker FETCH wINST, 0 // load wINST 1781*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip // extract opcode from wINST 1782*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip // jump to next instruction 1783*795d594fSAndroid Build Coastguard Worker3: 1784*795d594fSAndroid Build Coastguard Worker // Drop the current frame. 1785*795d594fSAndroid Build Coastguard Worker ldr ip, [xREFS, #-8] 1786*795d594fSAndroid Build Coastguard Worker mov sp, ip 1787*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa sp, CALLEE_SAVES_SIZE 1788*795d594fSAndroid Build Coastguard Worker 1789*795d594fSAndroid Build Coastguard Worker // The transition frame of type SaveAllCalleeSaves saves x19 and x20, 1790*795d594fSAndroid Build Coastguard Worker // but not managed ABI. So we need to restore callee-saves of the nterp frame, 1791*795d594fSAndroid Build Coastguard Worker // and save managed ABI callee saves, which will be restored by the callee upon 1792*795d594fSAndroid Build Coastguard Worker // return. 1793*795d594fSAndroid Build Coastguard Worker RESTORE_ALL_CALLEE_SAVES 1794*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME ((CALLEE_SAVES_SIZE) - 16) 1795*795d594fSAndroid Build Coastguard Worker 1796*795d594fSAndroid Build Coastguard Worker // FP callee-saves 1797*795d594fSAndroid Build Coastguard Worker stp d8, d9, [sp, #0] 1798*795d594fSAndroid Build Coastguard Worker stp d10, d11, [sp, #16] 1799*795d594fSAndroid Build Coastguard Worker stp d12, d13, [sp, #32] 1800*795d594fSAndroid Build Coastguard Worker stp d14, d15, [sp, #48] 1801*795d594fSAndroid Build Coastguard Worker 1802*795d594fSAndroid Build Coastguard Worker // GP callee-saves. 1803*795d594fSAndroid Build Coastguard Worker SAVE_TWO_REGS x21, x22, 64 1804*795d594fSAndroid Build Coastguard Worker SAVE_TWO_REGS x23, x24, 80 1805*795d594fSAndroid Build Coastguard Worker SAVE_TWO_REGS x25, x26, 96 1806*795d594fSAndroid Build Coastguard Worker SAVE_TWO_REGS x27, x28, 112 1807*795d594fSAndroid Build Coastguard Worker SAVE_TWO_REGS x29, lr, 128 1808*795d594fSAndroid Build Coastguard Worker 1809*795d594fSAndroid Build Coastguard Worker // Setup the new frame 1810*795d594fSAndroid Build Coastguard Worker ldr x1, [x0, #OSR_DATA_FRAME_SIZE] 1811*795d594fSAndroid Build Coastguard Worker // Given stack size contains all callee saved registers, remove them. 1812*795d594fSAndroid Build Coastguard Worker sub x1, x1, #(CALLEE_SAVES_SIZE - 16) 1813*795d594fSAndroid Build Coastguard Worker 1814*795d594fSAndroid Build Coastguard Worker // We know x1 cannot be 0, as it at least contains the ArtMethod. 1815*795d594fSAndroid Build Coastguard Worker 1816*795d594fSAndroid Build Coastguard Worker // Remember CFA in a callee-save register. 1817*795d594fSAndroid Build Coastguard Worker mov xINST, sp 1818*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa_register xINST 1819*795d594fSAndroid Build Coastguard Worker 1820*795d594fSAndroid Build Coastguard Worker sub sp, sp, x1 1821*795d594fSAndroid Build Coastguard Worker 1822*795d594fSAndroid Build Coastguard Worker add x2, x0, #OSR_DATA_MEMORY 1823*795d594fSAndroid Build Coastguard Worker4: 1824*795d594fSAndroid Build Coastguard Worker sub x1, x1, #8 1825*795d594fSAndroid Build Coastguard Worker ldr ip, [x2, x1] 1826*795d594fSAndroid Build Coastguard Worker str ip, [sp, x1] 1827*795d594fSAndroid Build Coastguard Worker cbnz x1, 4b 1828*795d594fSAndroid Build Coastguard Worker 1829*795d594fSAndroid Build Coastguard Worker // Fetch the native PC to jump to and save it in a callee-save register. 1830*795d594fSAndroid Build Coastguard Worker ldr xFP, [x0, #OSR_DATA_NATIVE_PC] 1831*795d594fSAndroid Build Coastguard Worker 1832*795d594fSAndroid Build Coastguard Worker // Free the memory holding OSR Data. 1833*795d594fSAndroid Build Coastguard Worker bl free 1834*795d594fSAndroid Build Coastguard Worker 1835*795d594fSAndroid Build Coastguard Worker // Jump to the compiled code. 1836*795d594fSAndroid Build Coastguard Worker br xFP 1837*795d594fSAndroid Build Coastguard Worker5: 1838*795d594fSAndroid Build Coastguard Worker DO_SUSPEND_CHECK continue_label=2b 1839*795d594fSAndroid Build Coastguard Worker b 2b 1840*795d594fSAndroid Build Coastguard Worker 1841*795d594fSAndroid Build Coastguard Worker// This is the logical end of ExecuteNterpImpl, where the frame info applies. 1842*795d594fSAndroid Build Coastguard Worker// EndExecuteNterpImpl includes the methods below as we want the runtime to 1843*795d594fSAndroid Build Coastguard Worker// see them as part of the Nterp PCs. 1844*795d594fSAndroid Build Coastguard Worker.cfi_endproc 1845*795d594fSAndroid Build Coastguard Worker 1846*795d594fSAndroid Build Coastguard Workernterp_to_nterp_static_non_range: 1847*795d594fSAndroid Build Coastguard Worker .cfi_startproc 1848*795d594fSAndroid Build Coastguard Worker SETUP_STACK_FOR_INVOKE 1849*795d594fSAndroid Build Coastguard Worker SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=1, is_string_init=0 1850*795d594fSAndroid Build Coastguard Worker .cfi_endproc 1851*795d594fSAndroid Build Coastguard Worker 1852*795d594fSAndroid Build Coastguard Workernterp_to_nterp_string_init_non_range: 1853*795d594fSAndroid Build Coastguard Worker .cfi_startproc 1854*795d594fSAndroid Build Coastguard Worker SETUP_STACK_FOR_INVOKE 1855*795d594fSAndroid Build Coastguard Worker SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=1 1856*795d594fSAndroid Build Coastguard Worker .cfi_endproc 1857*795d594fSAndroid Build Coastguard Worker 1858*795d594fSAndroid Build Coastguard Workernterp_to_nterp_instance_non_range: 1859*795d594fSAndroid Build Coastguard Worker .cfi_startproc 1860*795d594fSAndroid Build Coastguard Worker SETUP_STACK_FOR_INVOKE 1861*795d594fSAndroid Build Coastguard Worker SETUP_NON_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=0 1862*795d594fSAndroid Build Coastguard Worker .cfi_endproc 1863*795d594fSAndroid Build Coastguard Worker 1864*795d594fSAndroid Build Coastguard Workernterp_to_nterp_static_range: 1865*795d594fSAndroid Build Coastguard Worker .cfi_startproc 1866*795d594fSAndroid Build Coastguard Worker SETUP_STACK_FOR_INVOKE 1867*795d594fSAndroid Build Coastguard Worker SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=1 1868*795d594fSAndroid Build Coastguard Worker .cfi_endproc 1869*795d594fSAndroid Build Coastguard Worker 1870*795d594fSAndroid Build Coastguard Workernterp_to_nterp_instance_range: 1871*795d594fSAndroid Build Coastguard Worker .cfi_startproc 1872*795d594fSAndroid Build Coastguard Worker SETUP_STACK_FOR_INVOKE 1873*795d594fSAndroid Build Coastguard Worker SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0 1874*795d594fSAndroid Build Coastguard Worker .cfi_endproc 1875*795d594fSAndroid Build Coastguard Worker 1876*795d594fSAndroid Build Coastguard Workernterp_to_nterp_string_init_range: 1877*795d594fSAndroid Build Coastguard Worker .cfi_startproc 1878*795d594fSAndroid Build Coastguard Worker SETUP_STACK_FOR_INVOKE 1879*795d594fSAndroid Build Coastguard Worker SETUP_RANGE_ARGUMENTS_AND_EXECUTE is_static=0, is_string_init=1 1880*795d594fSAndroid Build Coastguard Worker .cfi_endproc 1881*795d594fSAndroid Build Coastguard Worker 1882*795d594fSAndroid Build Coastguard WorkerNAME_END nterp_helper 1883*795d594fSAndroid Build Coastguard Worker 1884*795d594fSAndroid Build Coastguard Worker// This is the end of PCs contained by the OatQuickMethodHeader created for the interpreter 1885*795d594fSAndroid Build Coastguard Worker// entry point. 1886*795d594fSAndroid Build Coastguard Worker .type EndExecuteNterpImpl, #function 1887*795d594fSAndroid Build Coastguard Worker .hidden EndExecuteNterpImpl 1888*795d594fSAndroid Build Coastguard Worker .global EndExecuteNterpImpl 1889*795d594fSAndroid Build Coastguard WorkerEndExecuteNterpImpl: 1890*795d594fSAndroid Build Coastguard Worker 1891*795d594fSAndroid Build Coastguard Worker// Entrypoints into runtime. 1892*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_static_field, NterpGetStaticField 1893*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_instance_field_offset, NterpGetInstanceFieldOffset 1894*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_filled_new_array, NterpFilledNewArray 1895*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_filled_new_array_range, NterpFilledNewArrayRange 1896*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_class, NterpGetClass 1897*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_allocate_object, NterpAllocateObject 1898*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_get_method, NterpGetMethod 1899*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_hot_method, NterpHotMethod 1900*795d594fSAndroid Build Coastguard WorkerNTERP_TRAMPOLINE nterp_load_object, NterpLoadObject 1901*795d594fSAndroid Build Coastguard Worker 1902*795d594fSAndroid Build Coastguard WorkerENTRY nterp_deliver_pending_exception 1903*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 1904*795d594fSAndroid Build Coastguard WorkerEND nterp_deliver_pending_exception 1905*795d594fSAndroid Build Coastguard Worker 1906*795d594fSAndroid Build Coastguard Worker// gen_mterp.py will inline the following definitions 1907*795d594fSAndroid Build Coastguard Worker// within [ExecuteNterpImpl, EndExecuteNterpImpl). 1908*795d594fSAndroid Build Coastguard Worker%def instruction_end(): 1909*795d594fSAndroid Build Coastguard Worker 1910*795d594fSAndroid Build Coastguard Worker .type artNterpAsmInstructionEnd, #function 1911*795d594fSAndroid Build Coastguard Worker .hidden artNterpAsmInstructionEnd 1912*795d594fSAndroid Build Coastguard Worker .global artNterpAsmInstructionEnd 1913*795d594fSAndroid Build Coastguard WorkerartNterpAsmInstructionEnd: 1914*795d594fSAndroid Build Coastguard Worker // artNterpAsmInstructionEnd is used as landing pad for exception handling. 1915*795d594fSAndroid Build Coastguard Worker FETCH_INST 1916*795d594fSAndroid Build Coastguard Worker GET_INST_OPCODE ip 1917*795d594fSAndroid Build Coastguard Worker GOTO_OPCODE ip 1918*795d594fSAndroid Build Coastguard Worker 1919*795d594fSAndroid Build Coastguard Worker%def instruction_start(): 1920*795d594fSAndroid Build Coastguard Worker 1921*795d594fSAndroid Build Coastguard Worker .type artNterpAsmInstructionStart, #function 1922*795d594fSAndroid Build Coastguard Worker .hidden artNterpAsmInstructionStart 1923*795d594fSAndroid Build Coastguard Worker .global artNterpAsmInstructionStart 1924*795d594fSAndroid Build Coastguard WorkerartNterpAsmInstructionStart = .L_op_nop 1925*795d594fSAndroid Build Coastguard Worker .text 1926*795d594fSAndroid Build Coastguard Worker 1927*795d594fSAndroid Build Coastguard Worker%def opcode_name_prefix(): 1928*795d594fSAndroid Build Coastguard Worker% return "nterp_" 1929*795d594fSAndroid Build Coastguard Worker%def opcode_start(): 1930*795d594fSAndroid Build Coastguard Worker NAME_START nterp_${opcode} 1931*795d594fSAndroid Build Coastguard Worker # Explicitly restore CFA, just in case the previous opcode clobbered it (by .cfi_def_*). 1932*795d594fSAndroid Build Coastguard Worker CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, CALLEE_SAVES_SIZE 1933*795d594fSAndroid Build Coastguard Worker%def opcode_end(): 1934*795d594fSAndroid Build Coastguard Worker NAME_END nterp_${opcode} 1935*795d594fSAndroid Build Coastguard Worker // Advance to the end of this handler. Causes error if we are past that point. 1936*795d594fSAndroid Build Coastguard Worker .org nterp_${opcode} + NTERP_HANDLER_SIZE // ${opcode} handler is too big! 1937*795d594fSAndroid Build Coastguard Worker%def opcode_slow_path_start(name): 1938*795d594fSAndroid Build Coastguard Worker NAME_START ${name} 1939*795d594fSAndroid Build Coastguard Worker%def opcode_slow_path_end(name): 1940*795d594fSAndroid Build Coastguard Worker NAME_END ${name} 1941