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