blob: 083dc152059163aa0f17d96d31d31d304ea11b7f [file] [log] [blame]
Douglas Leung200f0402016-02-25 20:05:47 -08001/*
2 * ===========================================================================
3 * Common subroutines and data
4 * ===========================================================================
5 */
6
7 .text
8 .align 2
9
10/*
11 * We've detected a condition that will result in an exception, but the exception
12 * has not yet been thrown. Just bail out to the reference interpreter to deal with it.
13 * TUNING: for consistency, we may want to just go ahead and handle these here.
14 */
15common_errDivideByZero:
16 EXPORT_PC()
17#if MTERP_LOGGING
18 move a0, rSELF
19 addu a1, rFP, OFF_FP_SHADOWFRAME
20 JAL(MterpLogDivideByZeroException)
21#endif
22 b MterpCommonFallback
23
24common_errArrayIndex:
25 EXPORT_PC()
26#if MTERP_LOGGING
27 move a0, rSELF
28 addu a1, rFP, OFF_FP_SHADOWFRAME
29 JAL(MterpLogArrayIndexException)
30#endif
31 b MterpCommonFallback
32
33common_errNegativeArraySize:
34 EXPORT_PC()
35#if MTERP_LOGGING
36 move a0, rSELF
37 addu a1, rFP, OFF_FP_SHADOWFRAME
38 JAL(MterpLogNegativeArraySizeException)
39#endif
40 b MterpCommonFallback
41
42common_errNoSuchMethod:
43 EXPORT_PC()
44#if MTERP_LOGGING
45 move a0, rSELF
46 addu a1, rFP, OFF_FP_SHADOWFRAME
47 JAL(MterpLogNoSuchMethodException)
48#endif
49 b MterpCommonFallback
50
51common_errNullObject:
52 EXPORT_PC()
53#if MTERP_LOGGING
54 move a0, rSELF
55 addu a1, rFP, OFF_FP_SHADOWFRAME
56 JAL(MterpLogNullObjectException)
57#endif
58 b MterpCommonFallback
59
60common_exceptionThrown:
61 EXPORT_PC()
62#if MTERP_LOGGING
63 move a0, rSELF
64 addu a1, rFP, OFF_FP_SHADOWFRAME
65 JAL(MterpLogExceptionThrownException)
66#endif
67 b MterpCommonFallback
68
69MterpSuspendFallback:
70 EXPORT_PC()
71#if MTERP_LOGGING
72 move a0, rSELF
73 addu a1, rFP, OFF_FP_SHADOWFRAME
74 lw a2, THREAD_FLAGS_OFFSET(rSELF)
75 JAL(MterpLogSuspendFallback)
76#endif
77 b MterpCommonFallback
78
79/*
80 * If we're here, something is out of the ordinary. If there is a pending
81 * exception, handle it. Otherwise, roll back and retry with the reference
82 * interpreter.
83 */
84MterpPossibleException:
85 lw a0, THREAD_EXCEPTION_OFFSET(rSELF)
86 beqz a0, MterpFallback # If exception, fall back to reference interpreter.
87 /* intentional fallthrough - handle pending exception. */
88/*
89 * On return from a runtime helper routine, we've found a pending exception.
90 * Can we handle it here - or need to bail out to caller?
91 *
92 */
93MterpException:
94 move a0, rSELF
95 addu a1, rFP, OFF_FP_SHADOWFRAME
96 JAL(MterpHandleException) # (self, shadow_frame)
97 beqz v0, MterpExceptionReturn # no local catch, back to caller.
98 lw a0, OFF_FP_CODE_ITEM(rFP)
99 lw a1, OFF_FP_DEX_PC(rFP)
100 lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
101 addu rPC, a0, CODEITEM_INSNS_OFFSET
102 sll a1, a1, 1
103 addu rPC, rPC, a1 # generate new dex_pc_ptr
104 /* Do we need to switch interpreters? */
105 JAL(MterpShouldSwitchInterpreters)
106 bnez v0, MterpFallback
107 /* resume execution at catch block */
108 EXPORT_PC()
109 FETCH_INST()
110 GET_INST_OPCODE(t0)
111 GOTO_OPCODE(t0)
112 /* NOTE: no fallthrough */
113
114/*
115 * Check for suspend check request. Assumes rINST already loaded, rPC advanced and
116 * still needs to get the opcode and branch to it, and flags are in lr.
117 */
118MterpCheckSuspendAndContinue:
119 lw rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF) # refresh rIBASE
120 and ra, (THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
121 bnez ra, 1f
122 GET_INST_OPCODE(t0) # extract opcode from rINST
123 GOTO_OPCODE(t0) # jump to next instruction
1241:
125 EXPORT_PC()
126 move a0, rSELF
127 JAL(MterpSuspendCheck) # (self)
128 bnez v0, MterpFallback
129 GET_INST_OPCODE(t0) # extract opcode from rINST
130 GOTO_OPCODE(t0) # jump to next instruction
131
132/*
133 * On-stack replacement has happened, and now we've returned from the compiled method.
134 */
135MterpOnStackReplacement:
136#if MTERP_LOGGING
137 move a0, rSELF
138 addu a1, rFP, OFF_FP_SHADOWFRAME
139 move a2, rINST
140 JAL(MterpLogOSR)
141#endif
142 li v0, 1 # Signal normal return
143 b MterpDone
144
145/*
146 * Bail out to reference interpreter.
147 */
148MterpFallback:
149 EXPORT_PC()
150#if MTERP_LOGGING
151 move a0, rSELF
152 addu a1, rFP, OFF_FP_SHADOWFRAME
153 JAL(MterpLogFallback)
154#endif
155MterpCommonFallback:
156 move v0, zero # signal retry with reference interpreter.
157 b MterpDone
158/*
159 * We pushed some registers on the stack in ExecuteMterpImpl, then saved
160 * SP and LR. Here we restore SP, restore the registers, and then restore
161 * LR to PC.
162 *
163 * On entry:
164 * uint32_t* rFP (should still be live, pointer to base of vregs)
165 */
166MterpExceptionReturn:
167 li v0, 1 # signal return to caller.
168 b MterpDone
169MterpReturn:
170 lw a2, OFF_FP_RESULT_REGISTER(rFP)
171 sw v0, 0(a2)
172 sw v1, 4(a2)
173 li v0, 1 # signal return to caller.
174MterpDone:
175/* Restore from the stack and return. Frame size = STACK_SIZE */
176 STACK_LOAD_FULL()
177 jalr zero, ra
178
179 .end ExecuteMterpImpl