1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In the C mterp stubs, "goto" is a function call followed immediately
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by a return.
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_TARGET_DECL(_target, ...)                                      \
7cd8f5e701547739f241594b43e9470c92d98e9cfCarl Shapiro    extern "C" void dvmMterp_##_target(Thread* self, ## __VA_ARGS__);
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97520ee7ff226e12e06818561b15741d2575072e3buzbee/* (void)xxx to quiet unused variable compiler warnings. */
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_TARGET(_target, ...)                                           \
119f601a917c8878204482c37aec7005054b6776fabuzbee    void dvmMterp_##_target(Thread* self, ## __VA_ARGS__) {                 \
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 ref, vsrc1, vsrc2, vdst;                                         \
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 inst = FETCH(0);                                                 \
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const Method* methodToCall;                                         \
157520ee7ff226e12e06818561b15741d2575072e3buzbee        StackSaveArea* debugSaveArea;                                       \
167520ee7ff226e12e06818561b15741d2575072e3buzbee        (void)ref; (void)vsrc1; (void)vsrc2; (void)vdst; (void)inst;        \
177520ee7ff226e12e06818561b15741d2575072e3buzbee        (void)methodToCall; (void)debugSaveArea;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_TARGET_END }
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
229f601a917c8878204482c37aec7005054b6776fabuzbee * Redefine what used to be local variable accesses into Thread struct
23bbf31b58c50fb892423b7fef0d8c1093bd0c1a6cBrian Carlstrom * references.  (These are undefined down in "footer.cpp".)
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
25cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee#define retval                  self->interpSave.retval
269f601a917c8878204482c37aec7005054b6776fabuzbee#define pc                      self->interpSave.pc
2730bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee#define fp                      self->interpSave.curFrame
289f601a917c8878204482c37aec7005054b6776fabuzbee#define curMethod               self->interpSave.method
299f601a917c8878204482c37aec7005054b6776fabuzbee#define methodClassDex          self->interpSave.methodClassDex
309f601a917c8878204482c37aec7005054b6776fabuzbee#define debugTrackedRefStart    self->interpSave.debugTrackedRefStart
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* ugh */
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define STUB_HACK(x) x
349a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT)
359a3147c7412f4794434b4c2604aa2ba784867774buzbee#define JIT_STUB_HACK(x) x
369a3147c7412f4794434b4c2604aa2ba784867774buzbee#else
379a3147c7412f4794434b4c2604aa2ba784867774buzbee#define JIT_STUB_HACK(x)
389a3147c7412f4794434b4c2604aa2ba784867774buzbee#endif
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4099e3e6e72e3471eb85fc2e405866392b01c080febuzbee/*
4199e3e6e72e3471eb85fc2e405866392b01c080febuzbee * InterpSave's pc and fp must be valid when breaking out to a
4299e3e6e72e3471eb85fc2e405866392b01c080febuzbee * "Reportxxx" routine.  Because the portable interpreter uses local
4399e3e6e72e3471eb85fc2e405866392b01c080febuzbee * variables for these, we must flush prior.  Stubs, however, use
4499e3e6e72e3471eb85fc2e405866392b01c080febuzbee * the interpSave vars directly, so this is a nop for stubs.
4599e3e6e72e3471eb85fc2e405866392b01c080febuzbee */
4699e3e6e72e3471eb85fc2e405866392b01c080febuzbee#define PC_FP_TO_SELF()
4730bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee#define PC_TO_SELF()
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Opcode handler framing macros.  Here, each opcode is a separate function
519f601a917c8878204482c37aec7005054b6776fabuzbee * that takes a "self" argument and returns void.  We can't declare
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * these "static" because they may be called from an assembly stub.
537520ee7ff226e12e06818561b15741d2575072e3buzbee * (void)xxx to quiet unused variable compiler warnings.
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OPCODE(_op)                                                  \
56cd8f5e701547739f241594b43e9470c92d98e9cfCarl Shapiro    extern "C" void dvmMterp_##_op(Thread* self);                           \
579f601a917c8878204482c37aec7005054b6776fabuzbee    void dvmMterp_##_op(Thread* self) {                                     \
586aed656b06aa274948bf5c5f8f65873814554c13Andy McFadden        u4 ref;                                                             \
596aed656b06aa274948bf5c5f8f65873814554c13Andy McFadden        u2 vsrc1, vsrc2, vdst;                                              \
607520ee7ff226e12e06818561b15741d2575072e3buzbee        u2 inst = FETCH(0);                                                 \
617520ee7ff226e12e06818561b15741d2575072e3buzbee        (void)ref; (void)vsrc1; (void)vsrc2; (void)vdst; (void)inst;
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define OP_END }
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Like the "portable" FINISH, but don't reload "inst", and return to caller
679a3147c7412f4794434b4c2604aa2ba784867774buzbee * when done.  Further, debugger/profiler checks are handled
689a3147c7412f4794434b4c2604aa2ba784867774buzbee * before handler execution in mterp, so we don't do them here either.
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
709a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT)
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define FINISH(_offset) {                                                   \
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ADJUST_PC(_offset);                                                 \
739a3147c7412f4794434b4c2604aa2ba784867774buzbee        if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) {        \
749a3147c7412f4794434b4c2604aa2ba784867774buzbee            dvmCheckJit(pc, self);                                          \
759a3147c7412f4794434b4c2604aa2ba784867774buzbee        }                                                                   \
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;                                                             \
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
789a3147c7412f4794434b4c2604aa2ba784867774buzbee#else
799a3147c7412f4794434b4c2604aa2ba784867774buzbee#define FINISH(_offset) {                                                   \
809a3147c7412f4794434b4c2604aa2ba784867774buzbee        ADJUST_PC(_offset);                                                 \
819a3147c7412f4794434b4c2604aa2ba784867774buzbee        return;                                                             \
829a3147c7412f4794434b4c2604aa2ba784867774buzbee    }
839a3147c7412f4794434b4c2604aa2ba784867774buzbee#endif
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8575425b731c514bf90c985275d80aa7886727d83fChris Dearman#define FINISH_BKPT(_opcode)       /* FIXME? */
8675425b731c514bf90c985275d80aa7886727d83fChris Dearman#define DISPATCH_EXTENDED(_opcode) /* FIXME? */
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The "goto label" statements turn into function calls followed by
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return statements.  Some of the functions take arguments, which in the
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * portable interpreter are handled by assigning values to globals.
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_exceptionThrown()                                              \
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {                                                                    \
969f601a917c8878204482c37aec7005054b6776fabuzbee        dvmMterp_exceptionThrown(self);                                     \
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;                                                             \
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while(false)
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_returnFromMethod()                                             \
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {                                                                    \
1029f601a917c8878204482c37aec7005054b6776fabuzbee        dvmMterp_returnFromMethod(self);                                    \
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;                                                             \
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while(false)
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
106ab35b50311951feea3782151dd5422ee944685c2Elliott Hughes#define GOTO_invoke(_target, _methodCallRange)                              \
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {                                                                    \
108ab35b50311951feea3782151dd5422ee944685c2Elliott Hughes        dvmMterp_##_target(self, _methodCallRange);                         \
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;                                                             \
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while(false)
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst)   \
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {                                                                    \
1149f601a917c8878204482c37aec7005054b6776fabuzbee        dvmMterp_invokeMethod(self, _methodCallRange, _methodToCall,        \
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            _vsrc1, _vdst);                                                 \
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;                                                             \
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while(false)
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1209a3147c7412f4794434b4c2604aa2ba784867774buzbee * As a special case, "goto bail" turns into a longjmp.
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GOTO_bail()                                                         \
12375425b731c514bf90c985275d80aa7886727d83fChris Dearman    dvmMterpStdBail(self)
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Periodically check for thread suspension.
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * While we're at it, see if a debugger has attached or the profiler has
1299a3147c7412f4794434b4c2604aa2ba784867774buzbee * started.
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1319a3147c7412f4794434b4c2604aa2ba784867774buzbee#define PERIODIC_CHECKS(_pcadj) {                              \
13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        if (dvmCheckSuspendQuick(self)) {                                   \
13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project            EXPORT_PC();  /* need for precise GC */                         \
13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project            dvmCheckSuspendPending(self);                                   \
13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        }                                                                   \
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
137