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 * 32-bit x86 definitions and declarations. 18 */ 19 20/* 21386 ABI general notes: 22 23Caller save set: 24 eax, edx, ecx, st(0)-st(7) 25Callee save set: 26 ebx, esi, edi, ebp 27Return regs: 28 32-bit in eax 29 64-bit in edx:eax (low-order 32 in eax) 30 fp on top of fp stack st(0) 31 32Parameters passed on stack, pushed right-to-left. On entry to target, first 33parm is at 4(%esp). Traditional entry code is: 34 35functEntry: 36 push %ebp # save old frame pointer 37 mov %ebp,%esp # establish new frame pointer 38 sub FrameSize,%esp # Allocate storage for spill, locals & outs 39 40Once past the prologue, arguments are referenced at ((argno + 2)*4)(%ebp) 41 42Alignment of stack not strictly required, but should be for performance. We'll 43align frame sizes to 16-byte multiples. 44 45If we're not doing variable stack allocation (alloca), the frame pointer can be 46eliminated and all arg references adjusted to be esp relative. 47 48Mterp notes: 49 50Some key interpreter variables will be assigned to registers. Note that each 51will also have an associated spill location (mostly used useful for those assigned 52to callee save registers). 53 54 nick reg purpose 55 rPC edx interpreted program counter, used for fetching instructions 56 rFP esi interpreted frame pointer, used for accessing locals and args 57 rIBASE edi Base pointer for instruction dispatch computed goto 58 rINST bx first 16-bit code of current instruction 59 rOPCODE bl opcode portion of instruction word 60 rINST_HI bh high byte of instruction word, usually contains src/tgt reg names 61 62Notes: 63 o High order 16 bits of ebx must be zero on entry to handler 64 o rPC, rFP, rIBASE, rINST/rOPCODE valid on handler entry and exit 65 o eax and ecx are scratch, rINST/ebx sometimes scratch 66 o rPC is in the caller save set, and will be killed across external calls. Don't 67 forget to SPILL/UNSPILL it around call points 68 69*/ 70 71#define rPC %edx 72#define rFP %esi 73#define rIBASE %edi 74#define rINST_FULL %ebx 75#define rINST %bx 76#define rINST_HI %bh 77#define rINST_LO %bl 78#define rOPCODE %bl 79 80 81/* Frame diagram while executing dvmMterpStdRun, high to low addresses */ 82#define IN_ARG0 ( 8) 83#define CALLER_RP ( 4) 84#define PREV_FP ( 0) /* <- dvmMterpStdRun ebp */ 85/* Spill offsets relative to %ebp */ 86#define EDI_SPILL ( -4) 87#define ESI_SPILL ( -8) 88#define EDX_SPILL (-12) /* <- esp following dmMterpStdRun header */ 89#define rPC_SPILL (-16) 90#define rFP_SPILL (-20) 91#define rGLUE_SPILL (-24) 92#define rIBASE_SPILL (-28) 93#define rINST_FULL_SPILL (-32) 94#define TMP_SPILL (-36) 95#define LOCAL0_OFFSET (-40) 96#define LOCAL1_OFFSET (-44) 97#define LOCAL2_OFFSET (-48) 98#define LOCAL3_OFFSET (-52) 99/* Out Arg offsets, relative to %sp */ 100#define OUT_ARG4 ( 16) 101#define OUT_ARG3 ( 12) 102#define OUT_ARG2 ( 8) 103#define OUT_ARG1 ( 4) 104#define OUT_ARG0 ( 0) /* <- dvmMterpStdRun esp */ 105 106#define SPILL(reg) movl reg##,reg##_SPILL(%ebp) 107#define UNSPILL(reg) movl reg##_SPILL(%ebp),reg 108#define SPILL_TMP(reg) movl reg,TMP_SPILL(%ebp) 109#define UNSPILL_TMP(reg) movl TMP_SPILL(%ebp),reg 110 111 112/* save/restore the PC and/or FP from the glue struct */ 113#define LOAD_PC_FROM_GLUE(_glu) movl offGlue_pc(_glu),rPC 114#define SAVE_PC_TO_GLUE(_glu) movl rPC,offGlue_pc(_glu) 115#define LOAD_FP_FROM_GLUE(_glu) movl offGlue_fp(_glu),rFP 116#define SAVE_FP_TO_GLUE(_glu) movl rFP,offGlue_fp(_glu) 117 118#define GET_GLUE(_reg) movl rGLUE_SPILL(%ebp),_reg 119 120/* The interpreter assumes a properly aligned stack on entry, and 121 * will preserve 16-byte alignment. 122 */ 123 124/* 125 * "export" the PC to the interpreted stack frame, f/b/o future exception 126 * objects. Must * be done *before* something calls dvmThrowException. 127 * 128 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e. 129 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc) 130 * 131 * It's okay to do this more than once. 132 */ 133#define EXPORT_PC() \ 134 movl rPC, (-sizeofStackSaveArea + offStackSaveArea_currentPc)(rFP) 135 136/* 137 * Given a frame pointer, find the stack save area. 138 * 139 * In C this is "((StackSaveArea*)(_fp) -1)". 140 */ 141#define SAVEAREA_FROM_FP(_reg, _fpreg) \ 142 leal -sizeofStackSaveArea(_fpreg),_reg 143 144/* 145 * Fetch the next instruction from rPC into rINST. Does not advance rPC. 146 */ 147#define FETCH_INST() movzwl (rPC),rINST_FULL 148 149/* 150 * Fetch the nth instruction word from rPC into rINST. Does not advance 151 * rPC, and _count is in words 152 */ 153#define FETCH_INST_WORD(_count) movzwl _count*2(rPC),rINST_FULL 154 155/* 156 * Fetch instruction word indexed (used for branching). 157 * Index is in instruction word units. 158 */ 159#define FETCH_INST_INDEXED(_reg) movzwl (rPC,_reg,2),rINST_FULL 160 161/* 162 * Extract the opcode of the instruction in rINST 163 */ 164#define EXTRACT_OPCODE(_reg) movzx rOPCODE,_reg 165 166/* 167 * Advance rPC by instruction count 168 */ 169#define ADVANCE_PC(_count) leal 2*_count(rPC),rPC 170 171/* 172 * Advance rPC by branch offset in register 173 */ 174#define ADVANCE_PC_INDEXED(_reg) leal (rPC,_reg,2),rPC 175 176/* 177 * Note: assumes opcode previously fetched and in rINST, and 178 * %eax is killable at this point. 179 */ 180#if 1 181.macro GOTO_NEXT 182 /* For computed next version */ 183 movzx rOPCODE,%eax 184 sall $$$handler_size_bits,%eax 185 addl rIBASE,%eax 186 jmp *%eax 187.endm 188#else 189 /* For jump table version */ 190.macro GOTO_NEXT 191 movzx rOPCODE,%eax 192 jmp *(rIBASE,%eax,4) 193.endm 194#endif 195 196/* 197 * Get/set the 32-bit value from a Dalvik register. 198 */ 199#define GET_VREG(_reg, _vreg) movl (rFP,_vreg,4),_reg 200#define SET_VREG(_reg, _vreg) movl _reg,(rFP,_vreg,4) 201#define GET_VREG_WORD(_reg, _vreg, _offset) movl 4*(_offset)(rFP,_vreg,4),_reg 202#define SET_VREG_WORD(_reg, _vreg, _offset) movl _reg,4*(_offset)(rFP,_vreg,4) 203 204/* 205 * This is a #include, not a %include, because we want the C pre-processor 206 * to expand the macros into assembler assignment statements. 207 */ 208#include "../common/asm-constants.h" 209 210