1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16/* 17 * ARMv5 definitions and declarations. 18 */ 19 20/* 21ARM EABI general notes: 22 23r0-r3 hold first 4 args to a method; they are not preserved across method calls 24r4-r8 are available for general use 25r9 is given special treatment in some situations, but not for us 26r10 (sl) seems to be generally available 27r11 (fp) is used by gcc (unless -fomit-frame-pointer is set) 28r12 (ip) is scratch -- not preserved across method calls 29r13 (sp) should be managed carefully in case a signal arrives 30r14 (lr) must be preserved 31r15 (pc) can be tinkered with directly 32 33r0 holds returns of <= 4 bytes 34r0-r1 hold returns of 8 bytes, low word in r0 35 36Callee must save/restore r4+ (except r12) if it modifies them. If VFP 37is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved, 38s0-s15 (d0-d7, q0-a3) do not need to be. 39 40Stack is "full descending". Only the arguments that don't fit in the first 4 41registers are placed on the stack. "sp" points at the first stacked argument 42(i.e. the 5th arg). 43 44VFP: single-precision results in s0, double-precision results in d0. 45 46In the EABI, "sp" must be 64-bit aligned on entry to a function, and any 4764-bit quantities (long long, double) must be 64-bit aligned. 48*/ 49 50/* 51Mterp and ARM notes: 52 53The following registers have fixed assignments: 54 55 reg nick purpose 56 r4 rPC interpreted program counter, used for fetching instructions 57 r5 rFP interpreted frame pointer, used for accessing locals and args 58 r6 rGLUE MterpGlue pointer 59 r7 rINST first 16-bit code unit of current instruction 60 r8 rIBASE interpreted instruction base pointer, used for computed goto 61 62Macros are provided for common operations. Each macro MUST emit only 63one instruction to make instruction-counting easier. They MUST NOT alter 64unspecified registers or condition codes. 65*/ 66 67/* single-purpose registers, given names for clarity */ 68#define rPC r4 69#define rFP r5 70#define rGLUE r6 71#define rINST r7 72#define rIBASE r8 73 74/* save/restore the PC and/or FP from the glue struct */ 75#define LOAD_PC_FROM_GLUE() ldr rPC, [rGLUE, #offGlue_pc] 76#define SAVE_PC_TO_GLUE() str rPC, [rGLUE, #offGlue_pc] 77#define LOAD_FP_FROM_GLUE() ldr rFP, [rGLUE, #offGlue_fp] 78#define SAVE_FP_TO_GLUE() str rFP, [rGLUE, #offGlue_fp] 79#define LOAD_PC_FP_FROM_GLUE() ldmia rGLUE, {rPC, rFP} 80#define SAVE_PC_FP_TO_GLUE() stmia rGLUE, {rPC, rFP} 81 82/* 83 * "export" the PC to the stack frame, f/b/o future exception objects. Must 84 * be done *before* something calls dvmThrowException. 85 * 86 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e. 87 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc) 88 * 89 * It's okay to do this more than once. 90 */ 91#define EXPORT_PC() \ 92 str rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)] 93 94/* 95 * Given a frame pointer, find the stack save area. 96 * 97 * In C this is "((StackSaveArea*)(_fp) -1)". 98 */ 99#define SAVEAREA_FROM_FP(_reg, _fpreg) \ 100 sub _reg, _fpreg, #sizeofStackSaveArea 101 102/* 103 * Fetch the next instruction from rPC into rINST. Does not advance rPC. 104 */ 105#define FETCH_INST() ldrh rINST, [rPC] 106 107/* 108 * Fetch the next instruction from the specified offset. Advances rPC 109 * to point to the next instruction. "_count" is in 16-bit code units. 110 * 111 * Because of the limited size of immediate constants on ARM, this is only 112 * suitable for small forward movements (i.e. don't try to implement "goto" 113 * with this). 114 * 115 * This must come AFTER anything that can throw an exception, or the 116 * exception catch may miss. (This also implies that it must come after 117 * EXPORT_PC().) 118 */ 119#define FETCH_ADVANCE_INST(_count) ldrh rINST, [rPC, #(_count*2)]! 120 121/* 122 * The operation performed here is similar to FETCH_ADVANCE_INST, except the 123 * src and dest registers are parameterized (not hard-wired to rPC and rINST). 124 */ 125#define PREFETCH_ADVANCE_INST(_dreg, _sreg, _count) \ 126 ldrh _dreg, [_sreg, #(_count*2)]! 127 128/* 129 * Fetch the next instruction from an offset specified by _reg. Updates 130 * rPC to point to the next instruction. "_reg" must specify the distance 131 * in bytes, *not* 16-bit code units, and may be a signed value. 132 * 133 * We want to write "ldrh rINST, [rPC, _reg, lsl #2]!", but some of the 134 * bits that hold the shift distance are used for the half/byte/sign flags. 135 * In some cases we can pre-double _reg for free, so we require a byte offset 136 * here. 137 */ 138#define FETCH_ADVANCE_INST_RB(_reg) ldrh rINST, [rPC, _reg]! 139 140/* 141 * Fetch a half-word code unit from an offset past the current PC. The 142 * "_count" value is in 16-bit code units. Does not advance rPC. 143 * 144 * The "_S" variant works the same but treats the value as signed. 145 */ 146#define FETCH(_reg, _count) ldrh _reg, [rPC, #(_count*2)] 147#define FETCH_S(_reg, _count) ldrsh _reg, [rPC, #(_count*2)] 148 149/* 150 * Fetch one byte from an offset past the current PC. Pass in the same 151 * "_count" as you would for FETCH, and an additional 0/1 indicating which 152 * byte of the halfword you want (lo/hi). 153 */ 154#define FETCH_B(_reg, _count, _byte) ldrb _reg, [rPC, #(_count*2+_byte)] 155 156/* 157 * Put the instruction's opcode field into the specified register. 158 */ 159#define GET_INST_OPCODE(_reg) and _reg, rINST, #255 160 161/* 162 * Put the prefetched instruction's opcode field into the specified register. 163 */ 164#define GET_PREFETCHED_OPCODE(_oreg, _ireg) and _oreg, _ireg, #255 165 166/* 167 * Begin executing the opcode in _reg. Because this only jumps within the 168 * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork. 169 */ 170#define GOTO_OPCODE(_reg) add pc, rIBASE, _reg, lsl #${handler_size_bits} 171#define GOTO_OPCODE_IFEQ(_reg) addeq pc, rIBASE, _reg, lsl #${handler_size_bits} 172#define GOTO_OPCODE_IFNE(_reg) addne pc, rIBASE, _reg, lsl #${handler_size_bits} 173 174/* 175 * Get/set the 32-bit value from a Dalvik register. 176 */ 177#define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2] 178#define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2] 179 180#if defined(WITH_JIT) 181#define GET_JIT_ENABLED(_reg) ldr _reg,[rGLUE,#offGlue_jitEnabled] 182#define GET_JIT_PROF_TABLE(_reg) ldr _reg,[rGLUE,#offGlue_pJitProfTable] 183#endif 184 185/* 186 * Convert a virtual register index into an address. 187 */ 188#define VREG_INDEX_TO_ADDR(_reg, _vreg) \ 189 add _reg, rFP, _vreg, lsl #2 190 191/* 192 * This is a #include, not a %include, because we want the C pre-processor 193 * to expand the macros into assembler assignment statements. 194 */ 195#include "../common/asm-constants.h" 196 197