67 asm(".global _asm_exec_MessageComplete "); |
67 asm(".global _asm_exec_MessageComplete "); |
68 asm("_asm_exec_MessageComplete: "); |
68 asm("_asm_exec_MessageComplete: "); |
69 |
69 |
70 #ifdef BTRACE_CLIENT_SERVER |
70 #ifdef BTRACE_CLIENT_SERVER |
71 asm("stmfd sp!,{r0,r1,ip,lr}"); |
71 asm("stmfd sp!,{r0,r1,ip,lr}"); |
72 asm("mov r2,r1"); // arg2 = aReason |
72 asm("mov r2,r1"); // arg2 = aReason |
73 asm("mov r1,r0"); // arg1 = aMsg |
73 asm("mov r1,r0"); // arg1 = aMsg |
74 asm("ldr r0,_messageCompleteTraceHeader"); // arg0 = header |
74 asm("ldr r0,_messageCompleteTraceHeader"); // arg0 = header |
75 asm("bl " CSM_ZN6BTrace4OutXEmmmm); |
75 asm("bl " CSM_ZN6BTrace4OutXEmmmm); |
76 asm("ldmfd sp!,{r0,r1,ip,lr}"); |
76 asm("ldmfd sp!,{r0,r1,ip,lr}"); |
77 #endif |
77 #endif |
78 |
78 |
79 asm("cmp ip, #%a0" : : "i" (RMessage2::EDisConnect)); |
79 asm("cmp ip, #%a0" : : "i" (RMessage2::EDisConnect)); |
80 asm("ldreq r0, [r0, #%a0]" : : "i" _FOFF(RMessageK,iSession)); |
80 asm("ldreq r0, [r0, #%a0]" : : "i" _FOFF(RMessageK,iSession)); |
81 asm("beq " CSM_ZN8DSession19CloseFromDisconnectEv ); // if disconnect, do it in C++ |
81 asm("beq " CSM_ZN8DSession19CloseFromDisconnectEv ); // if disconnect, do it in C++ |
82 asm("mov r2, r1 "); // r2=aReason |
82 |
|
83 asm("mov r2, r1 "); // r2 = aReason |
83 ASM_DEBUG2(Complete,r0,r2); |
84 ASM_DEBUG2(Complete,r0,r2); |
84 asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(RMessageK, iSession)); // r3=iSession |
85 asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(RMessageK, iSession)); // r3 = iSession |
85 |
86 asm("subs r1, ip, #%a0" : : "i" (RMessage2::EConnect)); // (m.iFunction == RMessage2::EConnect)? |
86 asm("subs r1, ip, #%a0" : : "i" (RMessage2::EConnect)); // (m.iFunction == RMessage2::EConnect)? |
87 asm("streq r1, [r3, #%a0] " : : "i" _FOFF(DSession, iConnectMsgPtr)); // iSession->iConnectMsgPtr = NULL |
87 asm("streq r1, [r3, #%a0] " : : "i" _FOFF(DSession, iConnectMsgPtr)); // iSession->iConnectMsgPtr = NULL |
88 asm("ldr r1, [r3, #%a0]" : : "i" _FOFF(DSession,iAccessCount)); // r1 = iSession->iAccessCount |
88 |
89 asm("cmp r1, #0 "); // iAccessCount = 0? |
89 asm("ldr r1, [r3, #%a0]" : : "i" _FOFF(DSession,iAccessCount)); // r1=iSession->iAccessCount |
|
90 asm("cmp r1, #0 "); // iAccessCount = 0? |
|
91 asm("beq 2f "); |
90 asm("beq 2f "); |
92 |
91 |
93 // if (!s->IsClosing()) |
92 // !s->IsClosing() |
94 asm("mov r1, r0"); // r1 = RMessageK ptr |
93 asm("mov r1, r0"); // r1 = RMessageK ptr |
95 asm("ldr r0, [r0, #%a0] " : : "i" _FOFF(RMessageK,iClient)); // r0=iClient |
94 asm("ldr r0, [r0, #%a0] " : : "i" _FOFF(RMessageK,iClient)); // r0 = iClient |
|
95 asm("ldrb ip, [r0, #%a0] " : : "i" _FOFF(DThread,iMState)); // ip = iClient->iMState |
|
96 asm("cmp ip, #%a0" : : "i" (DThread::EDead)); // (iMState == EDead)? |
|
97 asm("beq 1f "); |
|
98 |
|
99 // if (!s->IsClosing() && m.iClient->iMState != DThread::EDead) |
96 asm("mov ip, #1"); |
100 asm("mov ip, #1"); |
97 asm("str ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iServerLink.iNext)); // iServerLink.iNext=1 |
101 asm("str ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iServerLink.iNext)); // iServerLink.iNext=1 |
98 asm("b " CSM_ZN4Kern20QueueRequestCompleteEP7DThreadP14TClientRequesti); |
102 asm("b " CSM_ZN4Kern20QueueRequestCompleteEP7DThreadP14TClientRequesti); // tail call |
99 |
103 |
100 // if (s->IsClosing()) |
104 // m.iClient->iMState == DThread::EDead |
|
105 asm("1: "); // shuffle RMessageK and iFunction back to expected registers |
|
106 asm("ldr ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iFunction)); // refetch iFunction |
|
107 asm("mov r0, r1"); // r0 = RMessageK ptr |
|
108 |
|
109 // else (closing or dead) |
101 asm("2: "); |
110 asm("2: "); |
102 asm("cmp ip, #%a0" : : "i" (RMessage2::EConnect)); // (m.iFunction == RMessage2::EConnect)? |
111 asm("cmp ip, #%a0" : : "i" (RMessage2::EConnect)); // (m.iFunction == RMessage2::EConnect)? |
103 asm("beq 4f "); |
112 asm("bne 3f "); |
104 asm("3: "); |
113 |
105 asm("stmfd sp!, {r0,lr} "); |
114 // (closing or dead) and it's a connect msg |
106 asm("bl " CSM_ZN14TClientRequest5ResetEv); |
115 asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie)); // r2=iSession->iSessionCookie |
107 asm("ldmfd sp!, {r0,lr} "); |
|
108 asm("b " CSM_ZN9RMessageK8CloseRefEv); |
|
109 |
|
110 asm("4: "); |
|
111 // if closing & connect msg |
|
112 asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie)); // r2=iSession->iSessionCookie |
|
113 asm("teq r2, #0"); |
116 asm("teq r2, #0"); |
114 #ifdef _DEBUG |
117 #ifdef _DEBUG |
115 asm("beq nosession "); |
118 asm("beq nosession "); |
116 asm("ldr r1, [r3, #%a0] " : : "i" _FOFF(DSession, iServer)); // r1=iSession->iServer |
119 asm("ldr r1, [r3, #%a0] " : : "i" _FOFF(DSession, iServer)); // r1=iSession->iServer |
117 asm("cmp r1, #0 "); |
120 asm("cmp r1, #0 "); |
118 asm("beq noserver "); |
121 asm("beq noserver "); |
119 asm("ldr r2, [r3, #%a0] " : : "i" (_FOFF(DSession, iDisconnectMsgPtr))); // r2=iSession->iDisconnectMsgPtr |
122 asm("ldr r2, [r3, #%a0] " : : "i" (_FOFF(DSession, iDisconnectMsgPtr))); // r2=iSession->iDisconnectMsgPtr |
120 asm("ldr r2, [r2, #%a0] " : : "i" (_FOFF(RMessageK, iServerLink.iNext))); // r2=iDisconnectMsgPtr->iServerLink.iNext |
123 asm("ldr r2, [r2, #%a0] " : : "i" (_FOFF(RMessageK, iServerLink.iNext))); // r2=iDisconnectMsgPtr->iServerLink.iNext |
121 asm("cmp r2, #0 "); |
124 asm("cmp r2, #0 "); |
122 asm("beq __FaultMsgCompleteDiscNotSent "); // die if a session has been created and no disc msg sent |
125 asm("beq __FaultMsgCompleteDiscNotSent "); // tail call to die if a session has been created and no disc msg sent |
123 asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie)); // r2=iSession->iSessionCookie |
126 asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie)); // r2=iSession->iSessionCookie |
124 asm("noserver: "); |
127 asm("noserver: "); |
125 asm("teq r2, #0"); |
128 asm("teq r2, #0"); |
126 asm("nosession: "); |
129 asm("nosession: "); |
127 #endif //_DEBUG |
130 #endif //_DEBUG |
128 asm("moveq r0, r3 "); |
131 asm("moveq r0, r3 "); |
129 asm("beq __SendDiscMsg "); // if no session object to clean up, send disc msg in C++ |
132 asm("beq __SendDiscMsg "); // if no session object to clean up, tail call to send disc msg in C++ |
130 asm("b 3b "); // return |
133 |
|
134 asm("3: "); |
|
135 asm("stmfd sp!, {r0,lr} "); |
|
136 asm("bl " CSM_ZN14TClientRequest5ResetEv); |
|
137 asm("ldmfd sp!, {r0,lr} "); |
|
138 asm("b " CSM_ZN9RMessageK8CloseRefEv); // tail call |
131 |
139 |
132 #ifdef BTRACE_CLIENT_SERVER |
140 #ifdef BTRACE_CLIENT_SERVER |
133 asm("_messageCompleteTraceHeader:"); |
141 asm("_messageCompleteTraceHeader:"); |
134 asm(".word %a0" : : "i" (BTRACE_HEADER_C(12,BTrace::EClientServer,BTrace::EMessageComplete))); |
142 asm(".word %a0" : : "i" (BTRACE_HEADER_C(12,BTrace::EClientServer,BTrace::EMessageComplete))); |
135 asm("_messageDeliverTraceHeader:"); |
143 asm("_messageDeliverTraceHeader:"); |