1/*
2 * Copyright (C) 2016 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#define zero $$0  /* always zero */
18#define AT   $$at /* assembler temp */
19#define v0   $$2  /* return value */
20#define v1   $$3
21#define a0   $$4  /* argument registers */
22#define a1   $$5
23#define a2   $$6
24#define a3   $$7
25#define a4   $$8  /* expanded register arguments */
26#define a5   $$9
27#define a6   $$10
28#define a7   $$11
29#define ta0  $$8  /* alias */
30#define ta1  $$9
31#define ta2  $$10
32#define ta3  $$11
33#define t0   $$12 /* temp registers (not saved across subroutine calls) */
34#define t1   $$13
35#define t2   $$14
36#define t3   $$15
37
38#define s0   $$16 /* saved across subroutine calls (callee saved) */
39#define s1   $$17
40#define s2   $$18
41#define s3   $$19
42#define s4   $$20
43#define s5   $$21
44#define s6   $$22
45#define s7   $$23
46#define t8   $$24 /* two more temp registers */
47#define t9   $$25
48#define k0   $$26 /* kernel temporary */
49#define k1   $$27
50#define gp   $$28 /* global pointer */
51#define sp   $$29 /* stack pointer */
52#define s8   $$30 /* one more callee saved */
53#define ra   $$31 /* return address */
54
55#define f0   $$f0
56#define f1   $$f1
57#define f2   $$f2
58#define f3   $$f3
59#define f12  $$f12
60#define f13  $$f13
61
62/*
63 * It looks like the GNU assembler currently does not support the blec and bgtc
64 * idioms, which should translate into bgec and bltc respectively with swapped
65 * left and right register operands.
66 * TODO: remove these macros when the assembler is fixed.
67 */
68.macro blec lreg, rreg, target
69    bgec    \rreg, \lreg, \target
70.endm
71.macro bgtc lreg, rreg, target
72    bltc    \rreg, \lreg, \target
73.endm
74
75/*
76Mterp and MIPS64 notes:
77
78The following registers have fixed assignments:
79
80  reg nick      purpose
81  s0  rPC       interpreted program counter, used for fetching instructions
82  s1  rFP       interpreted frame pointer, used for accessing locals and args
83  s2  rSELF     self (Thread) pointer
84  s3  rINST     first 16-bit code unit of current instruction
85  s4  rIBASE    interpreted instruction base pointer, used for computed goto
86  s5  rREFS     base of object references in shadow frame  (ideally, we'll get rid of this later).
87  s6  rPROFILE  jit profile hotness countdown
88*/
89
90/* During bringup, we'll use the shadow frame model instead of rFP */
91/* single-purpose registers, given names for clarity */
92#define rPC      s0
93#define CFI_DEX  16  // DWARF register number of the register holding dex-pc (s0).
94#define CFI_TMP  4   // DWARF register number of the first argument register (a0).
95#define rFP      s1
96#define rSELF    s2
97#define rINST    s3
98#define rIBASE   s4
99#define rREFS    s5
100#define rPROFILE s6
101
102/*
103 * This is a #include, not a %include, because we want the C pre-processor
104 * to expand the macros into assembler assignment statements.
105 */
106#include "asm_support.h"
107#include "interpreter/cfi_asm_support.h"
108
109/*
110 * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs.  So,
111 * to access other shadow frame fields, we need to use a backwards offset.  Define those here.
112 */
113#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
114#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
115#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
116#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
117#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
118#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
119#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
120#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET)
121#define OFF_FP_SHADOWFRAME OFF_FP(0)
122
123#define MTERP_PROFILE_BRANCHES 1
124#define MTERP_LOGGING 0
125
126/*
127 * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects.  Must
128 * be done *before* something throws.
129 *
130 * It's okay to do this more than once.
131 *
132 * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
133 * dex byte codes.  However, the rest of the runtime expects dex pc to be an instruction
134 * offset into the code_items_[] array.  For effiency, we will "export" the
135 * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
136 * to convert to a dex pc when needed.
137 */
138.macro EXPORT_PC
139    sd      rPC, OFF_FP_DEX_PC_PTR(rFP)
140.endm
141
142/*
143 * Refresh handler table.
144 */
145.macro REFRESH_IBASE
146    ld      rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
147.endm
148
149/*
150 * Fetch the next instruction from rPC into rINST.  Does not advance rPC.
151 */
152.macro FETCH_INST
153    lhu     rINST, 0(rPC)
154.endm
155
156/* Advance rPC by some number of code units. */
157.macro ADVANCE count
158    daddu   rPC, rPC, (\count) * 2
159.endm
160
161/*
162 * Fetch the next instruction from an offset specified by _reg and advance xPC.
163 * xPC to point to the next instruction.  "_reg" must specify the distance
164 * in bytes, *not* 16-bit code units, and may be a signed value.  Must not set flags.
165 *
166 */
167.macro FETCH_ADVANCE_INST_RB reg
168    daddu   rPC, rPC, \reg
169    FETCH_INST
170.endm
171
172/*
173 * Fetch the next instruction from the specified offset.  Advances rPC
174 * to point to the next instruction.
175 *
176 * This must come AFTER anything that can throw an exception, or the
177 * exception catch may miss.  (This also implies that it must come after
178 * EXPORT_PC.)
179 */
180.macro FETCH_ADVANCE_INST count
181    ADVANCE \count
182    FETCH_INST
183.endm
184
185/*
186 * Similar to FETCH_ADVANCE_INST, but does not update rPC.  Used to load
187 * rINST ahead of possible exception point.  Be sure to manually advance rPC
188 * later.
189 */
190.macro PREFETCH_INST count
191    lhu     rINST, ((\count) * 2)(rPC)
192.endm
193
194/*
195 * Put the instruction's opcode field into the specified register.
196 */
197.macro GET_INST_OPCODE reg
198    and     \reg, rINST, 255
199.endm
200
201/*
202 * Begin executing the opcode in _reg.
203 */
204.macro GOTO_OPCODE reg
205    .set noat
206    sll     AT, \reg, 7
207    daddu   AT, rIBASE, AT
208    jic     AT, 0
209    .set at
210.endm
211
212/*
213 * Get/set the 32-bit value from a Dalvik register.
214 * Note, GET_VREG does sign extension to 64 bits while
215 * GET_VREG_U does zero extension to 64 bits.
216 * One is useful for arithmetic while the other is
217 * useful for storing the result value as 64-bit.
218 */
219.macro GET_VREG reg, vreg
220    .set noat
221    dlsa    AT, \vreg, rFP, 2
222    lw      \reg, 0(AT)
223    .set at
224.endm
225.macro GET_VREG_U reg, vreg
226    .set noat
227    dlsa    AT, \vreg, rFP, 2
228    lwu     \reg, 0(AT)
229    .set at
230.endm
231.macro GET_VREG_FLOAT reg, vreg
232    .set noat
233    dlsa    AT, \vreg, rFP, 2
234    lwc1    \reg, 0(AT)
235    .set at
236.endm
237.macro SET_VREG reg, vreg
238    .set noat
239    dlsa    AT, \vreg, rFP, 2
240    sw      \reg, 0(AT)
241    dlsa    AT, \vreg, rREFS, 2
242    sw      zero, 0(AT)
243    .set at
244.endm
245.macro SET_VREG_OBJECT reg, vreg
246    .set noat
247    dlsa    AT, \vreg, rFP, 2
248    sw      \reg, 0(AT)
249    dlsa    AT, \vreg, rREFS, 2
250    sw      \reg, 0(AT)
251    .set at
252.endm
253.macro SET_VREG_FLOAT reg, vreg
254    .set noat
255    dlsa    AT, \vreg, rFP, 2
256    swc1    \reg, 0(AT)
257    dlsa    AT, \vreg, rREFS, 2
258    sw      zero, 0(AT)
259    .set at
260.endm
261
262/*
263 * Get/set the 64-bit value from a Dalvik register.
264 * Avoid unaligned memory accesses.
265 * Note, SET_VREG_WIDE clobbers the register containing the value being stored.
266 * Note, SET_VREG_DOUBLE clobbers the register containing the Dalvik register number.
267 */
268.macro GET_VREG_WIDE reg, vreg
269    .set noat
270    dlsa    AT, \vreg, rFP, 2
271    lw      \reg, 0(AT)
272    lw      AT, 4(AT)
273    dinsu   \reg, AT, 32, 32
274    .set at
275.endm
276.macro GET_VREG_DOUBLE reg, vreg
277    .set noat
278    dlsa    AT, \vreg, rFP, 2
279    lwc1    \reg, 0(AT)
280    lw      AT, 4(AT)
281    mthc1   AT, \reg
282    .set at
283.endm
284.macro SET_VREG_WIDE reg, vreg
285    .set noat
286    dlsa    AT, \vreg, rFP, 2
287    sw      \reg, 0(AT)
288    drotr32 \reg, \reg, 0
289    sw      \reg, 4(AT)
290    dlsa    AT, \vreg, rREFS, 2
291    sw      zero, 0(AT)
292    sw      zero, 4(AT)
293    .set at
294.endm
295.macro SET_VREG_DOUBLE reg, vreg
296    .set noat
297    dlsa    AT, \vreg, rREFS, 2
298    sw      zero, 0(AT)
299    sw      zero, 4(AT)
300    dlsa    AT, \vreg, rFP, 2
301    swc1    \reg, 0(AT)
302    mfhc1   \vreg, \reg
303    sw      \vreg, 4(AT)
304    .set at
305.endm
306
307/*
308 * On-stack offsets for spilling/unspilling callee-saved registers
309 * and the frame size.
310 */
311#define STACK_OFFSET_RA 0
312#define STACK_OFFSET_GP 8
313#define STACK_OFFSET_S0 16
314#define STACK_OFFSET_S1 24
315#define STACK_OFFSET_S2 32
316#define STACK_OFFSET_S3 40
317#define STACK_OFFSET_S4 48
318#define STACK_OFFSET_S5 56
319#define STACK_OFFSET_S6 64
320#define STACK_SIZE      80    /* needs 16 byte alignment */
321
322/* Constants for float/double_to_int/long conversions */
323#define INT_MIN             0x80000000
324#define INT_MIN_AS_FLOAT    0xCF000000
325#define INT_MIN_AS_DOUBLE   0xC1E0000000000000
326#define LONG_MIN            0x8000000000000000
327#define LONG_MIN_AS_FLOAT   0xDF000000
328#define LONG_MIN_AS_DOUBLE  0xC3E0000000000000
329