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