• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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