|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32\common\arm\cdes16.cia |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32cia.h> |
|
19 #include "../common.h" |
|
20 |
|
21 #if defined(__DES16_MACHINE_CODED__) || defined(__EABI__) |
|
22 |
|
23 GLREF_C void Des16PanicBadDesType(); |
|
24 GLREF_C void Des16PanicPosOutOfRange(); |
|
25 |
|
26 #endif |
|
27 |
|
28 #ifdef __DES16_MACHINE_CODED__ |
|
29 |
|
30 GLREF_C void Des16PanicLengthNegative(); |
|
31 GLREF_C void Des16PanicMaxLengthNegative(); |
|
32 GLREF_C void Des16PanicLengthOutOfRange(); |
|
33 GLREF_C void Des16PanicDesOverflow(); |
|
34 GLREF_C void Des16PanicDesIndexOutOfRange(); |
|
35 |
|
36 __NAKED__ EXPORT_C const TUint16 *TDesC16::Ptr() const |
|
37 // |
|
38 // Return a pointer to the buffer. |
|
39 // |
|
40 { |
|
41 asm("ldr r1, [r0], #4 "); |
|
42 asm("cmp r1, #0x50000000 "); |
|
43 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
44 asm("eor r1, r1, r1, lsr #1 "); |
|
45 asm("msr cpsr_flg, r1 "); |
|
46 asm("addcs r0, r0, #4 "); |
|
47 asm("ldrle r0, [r0] "); |
|
48 asm("addeq r0, r0, #4 "); |
|
49 __JUMP(,lr); |
|
50 } |
|
51 |
|
52 #ifndef __EABI_CTORS__ |
|
53 __NAKED__ EXPORT_C TPtrC16::TPtrC16() |
|
54 // |
|
55 // Default constructor |
|
56 // |
|
57 { |
|
58 asm("mov r1, #0x10000000 "); // type=EPtrC, length=0 |
|
59 asm("mov r2, #0 "); // ptr=NULL |
|
60 asm("stmia r0, {r1,r2} "); |
|
61 __JUMP(,lr); |
|
62 } |
|
63 |
|
64 __NAKED__ EXPORT_C TPtrC16::TPtrC16(const TDesC16& /*aDes*/) |
|
65 // |
|
66 // Constructor |
|
67 // |
|
68 { |
|
69 asm("ldr r2, [r1], #4 "); // r2 = type/length |
|
70 asm("bic r3, r2, #0xF0000000"); // r3 = length |
|
71 asm("orr r3, r3, #0x10000000"); // r3 = EPtrC + length |
|
72 asm("cmp r2, #0x50000000 "); |
|
73 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
74 asm("eor r2, r2, r2, lsr #1 "); |
|
75 asm("msr cpsr_flg, r2 "); |
|
76 asm("addcs r1, r1, #4 "); |
|
77 asm("ldrle r1, [r1] "); |
|
78 asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr() |
|
79 asm("str r3, [r0] "); |
|
80 asm("str r1, [r0, #4] "); |
|
81 __JUMP(,lr); |
|
82 } |
|
83 |
|
84 #ifdef __DES16_MACHINE_CODED_HWORD__ |
|
85 __NAKED__ EXPORT_C TPtrC16::TPtrC16(const TUint16* /*aString*/) |
|
86 // |
|
87 // Constructor |
|
88 // |
|
89 { |
|
90 asm("mov r2, r1 "); // save aString address |
|
91 asm("1: "); |
|
92 asm("ldrh r3, [r1], #2 "); |
|
93 asm("cmp r3, #0 "); |
|
94 asm("bne 1b "); // loop until we reach zero terminator |
|
95 asm("rsb r1, r2, r1 "); // r1 = 2*length + 2 |
|
96 asm("sub r1, r1, #2 "); // r1 = 2*length |
|
97 asm("mov r1, r1, lsr #1 "); // r1 = length |
|
98 asm("orr r1, r1, #0x10000000 "); // r1=EPtrC + length |
|
99 asm("stmia r0, {r1, r2} "); // store type/length and ptr fields |
|
100 __JUMP(,lr); |
|
101 } |
|
102 #endif |
|
103 |
|
104 __NAKED__ EXPORT_C TPtrC16::TPtrC16(const TUint16* /*aBuf*/,TInt /*aLength*/) |
|
105 // |
|
106 // Constructor |
|
107 // |
|
108 { |
|
109 asm("orrs r2, r2, #0x10000000 "); |
|
110 asm("strpl r2, [r0] "); |
|
111 asm("strpl r1, [r0, #4] "); |
|
112 __JUMP(pl,lr); |
|
113 asm("b " CSM_Z24Des16PanicLengthNegativev); |
|
114 } |
|
115 |
|
116 __NAKED__ EXPORT_C TPtr16::TPtr16(TUint16* /*aBuf*/,TInt /*aMaxLength*/) |
|
117 // |
|
118 // Constructor |
|
119 // |
|
120 { |
|
121 asm("cmp r2, #0 "); |
|
122 asm("movpl r3, r1 "); |
|
123 asm("movpl r1, #0x20000000 "); // length=0, EPtr |
|
124 asm("stmplia r0, {r1,r2,r3} "); |
|
125 __JUMP(pl,lr); |
|
126 asm("b " CSM_Z27Des16PanicMaxLengthNegativev); |
|
127 } |
|
128 |
|
129 __NAKED__ EXPORT_C TPtr16::TPtr16(TUint16* /*aBuf*/,TInt /*aLength*/,TInt /*aMaxLength*/) |
|
130 // |
|
131 // Constructor |
|
132 // |
|
133 { |
|
134 asm("cmp r2, #0 "); // check length>=0 |
|
135 asm("cmpge r3, r2 "); // if so, check maxlength>=length |
|
136 asm("movge r12, r1 "); |
|
137 asm("orrge r2, r2, #0x20000000 "); // r2 = length + EPtr |
|
138 asm("stmgeia r0, {r2,r3,r12} "); |
|
139 __JUMP(ge,lr); |
|
140 asm("cmp r2, #0 "); |
|
141 asm("bmi " CSM_Z24Des16PanicLengthNegativev); |
|
142 asm("cmp r3, #0 "); |
|
143 asm("bmi " CSM_Z27Des16PanicMaxLengthNegativev); |
|
144 asm("b " CSM_Z26Des16PanicLengthOutOfRangev); |
|
145 } |
|
146 |
|
147 __NAKED__ EXPORT_C TPtr16::TPtr16(TBufCBase16& /*aLcb*/,TInt /*aMaxLength*/) |
|
148 // |
|
149 // Constructor |
|
150 // |
|
151 { |
|
152 asm("mov r3, r1 "); |
|
153 asm("ldr r1, [r3] "); |
|
154 asm("bic r1, r1, #0xF0000000 "); // r1=aLcb.Length() |
|
155 asm("cmp r1, r2 "); // check against maxlength |
|
156 asm("orrle r1, r1, #0x40000000 "); // r1=aLcb.Length() + EBufCPtr |
|
157 asm("stmleia r0, {r1,r2,r3} "); |
|
158 __JUMP(le,lr); |
|
159 asm("b " CSM_Z26Des16PanicLengthOutOfRangev); |
|
160 } |
|
161 |
|
162 __NAKED__ EXPORT_C TBufCBase16::TBufCBase16() |
|
163 // |
|
164 // Constructor |
|
165 // |
|
166 { |
|
167 asm("mov r1, #0 "); |
|
168 asm("str r1, [r0] "); |
|
169 __JUMP(,lr); |
|
170 } |
|
171 |
|
172 #ifdef __DES16_MACHINE_CODED_HWORD__ |
|
173 __NAKED__ EXPORT_C TBufCBase16::TBufCBase16(const TUint16* /*aString*/,TInt /*aMaxLength*/) |
|
174 // |
|
175 // Constructor |
|
176 // |
|
177 { |
|
178 asm("sub r3, r1, #2 "); // r3=aString address-2 |
|
179 asm("1: "); |
|
180 asm("ldrh r12, [r3, #2]! "); |
|
181 asm("cmp r12, #0 "); |
|
182 asm("bne 1b "); // loop until we reach zero terminator |
|
183 asm("sub r3, r3, r1 "); // r3 = 2*length |
|
184 asm("mov r3, r3, lsr #1 "); // r3 = length (+EBufC) |
|
185 asm("cmp r3, r2 "); // check against max length |
|
186 asm("bgt Des16PanicLengthOutOfRange__Fv "); |
|
187 asm("stmfd sp!, {r0,lr} "); // save registers for function call |
|
188 asm("str r3, [r0], #4 "); // save length/type field, r0->buffer |
|
189 asm("add r2, r3, r3 "); // size=2*length into r2 for function call |
|
190 asm("bl memmove "); // call memmove |
|
191 __POPRET("r0,"); |
|
192 } |
|
193 #endif |
|
194 |
|
195 __NAKED__ EXPORT_C TBufCBase16::TBufCBase16(const TDesC16& /*aDes*/,TInt /*aMaxLength*/) |
|
196 // |
|
197 // Constructor |
|
198 // |
|
199 { |
|
200 asm("ldr r3, [r1], #4 "); // r3 = type/length |
|
201 asm("bic r12, r3, #0xF0000000"); // r12 = length |
|
202 asm("cmp r12, r2 "); // compare with maxlength |
|
203 asm("bgt " CSM_Z26Des16PanicLengthOutOfRangev); |
|
204 asm("cmp r3, #0x50000000 "); |
|
205 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
206 asm("eor r3, r3, r3, lsr #1 "); |
|
207 asm("msr cpsr_flg, r3 "); |
|
208 asm("addcs r1, r1, #4 "); |
|
209 asm("ldrle r1, [r1] "); |
|
210 asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr() |
|
211 asm("stmfd sp!, {r0,lr} "); // save registers for function call |
|
212 asm("str r12, [r0], #4 "); // store length/type, r0->buffer |
|
213 asm("add r2, r12, r12 "); // size=2*length into r2 for function call |
|
214 asm("bl memmove "); // call memmove |
|
215 __POPRET("r0,"); |
|
216 } |
|
217 #endif |
|
218 |
|
219 #ifdef __DES16_MACHINE_CODED_HWORD__ |
|
220 __NAKED__ EXPORT_C void TBufCBase16::Copy(const TUint16* /*aString*/,TInt /*aMaxLength*/) |
|
221 // |
|
222 // Copy from a string. |
|
223 // |
|
224 { |
|
225 asm("sub r3, r1, #2 "); // r3=aString address-2 |
|
226 asm("1: "); |
|
227 asm("ldrh r12, [r3, #2]! "); |
|
228 asm("cmp r12, #0 "); |
|
229 asm("bne 1b "); // loop until we reach zero terminator |
|
230 asm("sub r3, r3, r1 "); // r3 = 2*length |
|
231 asm("mov r3, r3, lsr #1 "); // r3 = length (+EBufC) |
|
232 asm("cmp r3, r2 "); // check against max length |
|
233 asm("bgt Des16PanicLengthOutOfRange__Fv "); |
|
234 asm("str r3, [r0], #4 "); // save length/type field, r0->buffer |
|
235 asm("add r2, r3, r3 "); // size=2*length into r2 for function call |
|
236 asm("b memmove "); // call memmove |
|
237 } |
|
238 #endif |
|
239 |
|
240 __NAKED__ EXPORT_C void TBufCBase16::Copy(const TDesC16& /*aDes*/,TInt /*aMaxLength*/) |
|
241 // |
|
242 // Copy from a descriptor. |
|
243 // |
|
244 { |
|
245 asm("ldr r3, [r1], #4 "); // r3 = type/length |
|
246 asm("bic r12, r3, #0xF0000000"); // r12 = length |
|
247 asm("cmp r12, r2 "); // compare with maxlength |
|
248 asm("bgt " CSM_Z21Des16PanicDesOverflowv); |
|
249 asm("cmp r3, #0x50000000 "); |
|
250 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
251 asm("eor r3, r3, r3, lsr #1 "); |
|
252 asm("msr cpsr_flg, r3 "); |
|
253 asm("addcs r1, r1, #4 "); |
|
254 asm("ldrle r1, [r1] "); |
|
255 asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr() |
|
256 asm("str r12, [r0], #4 "); // store length/type, r0->buffer |
|
257 asm("add r2, r12, r12 "); // size=2*length into r2 for function call |
|
258 asm("b memmove "); // call memmove |
|
259 } |
|
260 |
|
261 #ifndef __EABI_CTORS__ |
|
262 __NAKED__ EXPORT_C TBufBase16::TBufBase16(TInt /*aMaxLength*/) |
|
263 { |
|
264 asm("mov r2, #0x30000000 "); // EBuf + zero length |
|
265 asm("str r2, [r0] "); |
|
266 asm("str r1, [r0, #4] "); |
|
267 __JUMP(,lr); |
|
268 } |
|
269 |
|
270 __NAKED__ EXPORT_C TBufBase16::TBufBase16(TInt /*aLength*/, TInt /*aMaxLength*/) |
|
271 { |
|
272 asm("cmp r1, #0 "); // check length>=0 |
|
273 asm("cmpge r2, r1 "); // if so, check maxlength>=length |
|
274 asm("orrge r1, r1, #0x30000000 "); // r1=length + EBuf |
|
275 asm("stmgeia r0, {r1,r2} "); // store length/type and maxlength fields |
|
276 __JUMP(ge,lr); |
|
277 asm("cmp r2, #0 "); |
|
278 asm("bmi " CSM_Z27Des16PanicMaxLengthNegativev); |
|
279 asm("b " CSM_Z26Des16PanicLengthOutOfRangev); |
|
280 } |
|
281 |
|
282 #ifdef __DES16_MACHINE_CODED_HWORD__ |
|
283 __NAKED__ EXPORT_C TBufBase16::TBufBase16(const TUint16* /*aString*/, TInt /*aMaxLength*/) |
|
284 { |
|
285 asm("mov r12, r1, lsr #1 "); // save aString pointer (lose bottom bit which should be 0) |
|
286 asm("1: "); |
|
287 asm("ldrh r3, [r1], #2 "); |
|
288 asm("cmp r3, #0 "); |
|
289 asm("bne 1b "); // loop until we reach zero terminator |
|
290 asm("rsb r3, r12, r1, lsr #1 "); // r3 = length + 1 |
|
291 asm("sub r3, r3, #1 "); // r3 = length |
|
292 asm("cmp r3, r2 "); // compare to max length |
|
293 asm("bgt Des16PanicLengthOutOfRange__Fv "); // length too big, so panic |
|
294 asm("orr r1, r3, #0x30000000 "); // if length<=max, r1=EBuf + length |
|
295 asm("stmfd sp!, {r0, lr} "); // save registers for function call |
|
296 asm("stmia r0!, {r1, r2} "); // store type/length and max length fields, r0->buffer |
|
297 asm("mov r2, r3, lsl #1 "); // r2=Size() |
|
298 asm("mov r1, r12, lsl #1 "); // r1=aString |
|
299 asm("bl memmove "); // call memmove |
|
300 __POPRET("r0,"); |
|
301 } |
|
302 #endif |
|
303 |
|
304 __NAKED__ EXPORT_C TBufBase16::TBufBase16(const TDesC16& /*aDes*/, TInt /*aMaxLength*/) |
|
305 { |
|
306 asm("ldr r3, [r1], #4 "); // r3 = type/length |
|
307 asm("bic r12, r3, #0xF0000000"); // r12 = length |
|
308 asm("cmp r12, r2 "); // compare with maxlength |
|
309 asm("bgt " CSM_Z26Des16PanicLengthOutOfRangev); |
|
310 asm("cmp r3, #0x50000000 "); |
|
311 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
312 asm("eor r3, r3, r3, lsr #1 "); |
|
313 asm("msr cpsr_flg, r3 "); |
|
314 asm("addcs r1, r1, #4 "); |
|
315 asm("ldrle r1, [r1] "); |
|
316 asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr() |
|
317 asm("stmfd sp!, {r0,lr} "); // save registers for function call |
|
318 asm("orr r3, r12, #0x30000000 "); // add EBuf type field |
|
319 asm("str r3, [r0], #4 "); // store length/type, r0->max length |
|
320 asm("str r2, [r0], #4 "); // store max length, r0->buffer |
|
321 asm("mov r2, r12, lsl #1 "); // Size() into r2 for function call |
|
322 asm("bl memmove "); // call memmove |
|
323 __POPRET("r0,"); |
|
324 } |
|
325 #endif |
|
326 |
|
327 __NAKED__ EXPORT_C void TDes16::SetLength(TInt /*aLength*/) |
|
328 // |
|
329 // Set the length of the descriptor, checking the length is O.K. |
|
330 // |
|
331 { |
|
332 asm("ldmia r0, {r2,r3} "); // r2=length/type, r3=maxlength |
|
333 asm("cmp r1, r3 "); // check aLength against maxlength and for -ve values |
|
334 asm("bhi " CSM_Z21Des16PanicDesOverflowv); |
|
335 asm("and r2, r2, #0xF0000000 "); // r2=type field |
|
336 asm("cmp r2, #0x40000000 "); // check for EBufCPtr |
|
337 asm("orr r2, r2, r1 "); // r2=type + new length |
|
338 asm("str r2, [r0] "); // store new length |
|
339 __JUMP(ne,lr); |
|
340 asm("ldr r2, [r0, #8] "); // r2=pointer to TBufCBase |
|
341 asm("str r1, [r2] "); // update length of TBufCBase |
|
342 __JUMP(,lr); |
|
343 } |
|
344 |
|
345 __NAKED__ EXPORT_C void TDes16::SetMax() |
|
346 // |
|
347 // Set the length to MaxLength(). |
|
348 // |
|
349 { |
|
350 asm("ldmia r0, {r1,r2} "); // r1=length/type, r2=maxlength |
|
351 asm("and r1, r1, #0xF0000000 "); // r1=type field |
|
352 asm("cmp r1, #0x40000000 "); // check for EBufCPtr |
|
353 asm("orr r1, r1, r2 "); // r1=type field + maxlength |
|
354 asm("str r1, [r0] "); // store new length |
|
355 __JUMP(ne,lr); |
|
356 asm("ldr r1, [r0, #8] "); // r1 = pointer to TBufCBase |
|
357 asm("str r2, [r1] "); // update length of TBufCBase |
|
358 __JUMP(,lr); |
|
359 } |
|
360 |
|
361 #ifdef __DES16_MACHINE_CODED_HWORD__ |
|
362 __NAKED__ EXPORT_C void TDes16::Copy(const TUint16* /*aString*/) |
|
363 // |
|
364 // Copy a string to this descriptor. |
|
365 // |
|
366 { |
|
367 asm("sub r2, r1, #2 "); // r2=aString-2 |
|
368 asm("1: "); |
|
369 asm("ldrh r3, [r2, #2]! "); |
|
370 asm("cmp r3, #0 "); |
|
371 asm("bne 1b "); // loop until zero terminator reached |
|
372 asm("sub r2, r2, r1 "); // r2=2*length of string |
|
373 asm("mov r2, r2, lsr #1 "); // r2=length of string |
|
374 asm("ldmia r0, {r3,r12} "); // r3=type/length of this, r12=maxlength |
|
375 asm("cmp r2, r12 "); // compare new length against maxlength |
|
376 asm("bgt Des16PanicDesOverflow__Fv "); |
|
377 asm("cmp r3, #0x50000000 "); |
|
378 asm("bcs Des16PanicBadDesType__Fv "); |
|
379 asm("and r3, r3, #0xF0000000 "); // r3=type of this |
|
380 asm("orr r3, r3, r2 "); // r3=new type/length |
|
381 asm("str r3, [r0], #4 "); // store it |
|
382 asm("eor r3, r3, r3, lsr #1 "); |
|
383 asm("msr cpsr_flg, r3 "); |
|
384 asm("addcs r0, r0, #4 "); |
|
385 asm("ldrle r0, [r0] "); |
|
386 asm("streq r2, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr() |
|
387 asm("add r2, r2, r2 "); // r2=size=2*length |
|
388 asm("b memmove "); // call memmove |
|
389 } |
|
390 #endif |
|
391 |
|
392 __NAKED__ EXPORT_C void TDes16::Copy(const TUint16* /*aBuf*/,TInt /*aLength*/) |
|
393 // |
|
394 // Copy the aLength characters to the descriptor. |
|
395 // |
|
396 { |
|
397 asm("ldmia r0, {r3,r12} "); // r3=type/length of this, r12=maxlength |
|
398 asm("cmp r2, r12 "); // compare new length against maxlength |
|
399 asm("bhi " CSM_Z21Des16PanicDesOverflowv); // Des16Panic if >MaxLength or -ve |
|
400 asm("cmp r3, #0x50000000 "); |
|
401 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
402 asm("and r3, r3, #0xF0000000 "); // r3=type of this |
|
403 asm("orr r3, r3, r2 "); // r3=new type/length |
|
404 asm("str r3, [r0], #4 "); // store it |
|
405 asm("eor r3, r3, r3, lsr #1 "); |
|
406 asm("msr cpsr_flg, r3 "); |
|
407 asm("addcs r0, r0, #4 "); |
|
408 asm("ldrle r0, [r0] "); |
|
409 asm("streq r2, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr() |
|
410 asm("add r2, r2, r2 "); // r2=size=2*length |
|
411 asm("b memmove "); // call memmove |
|
412 } |
|
413 |
|
414 __NAKED__ EXPORT_C void TDes16::Copy(const TDesC16& /*aDes*/) |
|
415 // |
|
416 // Copy a descriptor to this descriptor. |
|
417 // |
|
418 { |
|
419 asm("ldr r3, [r1], #4 "); // r3 = type/length of aDes |
|
420 asm("bic r12, r3, #0xF0000000"); // r12 = aDes.length |
|
421 asm("ldr r2, [r0, #4] "); // r2=this.maxlength |
|
422 asm("cmp r12, r2 "); // compare with maxlength |
|
423 asm("bgt " CSM_Z21Des16PanicDesOverflowv); |
|
424 asm("ldr r2, [r0] "); // get type of this |
|
425 asm("cmp r2, #0x50000000 "); // check both descriptor types |
|
426 asm("cmpcc r3, #0x50000000 "); |
|
427 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
428 asm("and r2, r2, #0xF0000000 "); |
|
429 asm("orr r2, r12, r2 "); // r2=new type/length of this |
|
430 asm("str r2, [r0], #4 "); // store it |
|
431 asm("eor r3, r3, r3, lsr #1 "); |
|
432 asm("msr cpsr_flg, r3 "); |
|
433 asm("addcs r1, r1, #4 "); |
|
434 asm("ldrle r1, [r1] "); |
|
435 asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr() |
|
436 asm("eor r2, r2, r2, lsr #1 "); |
|
437 asm("msr cpsr_flg, r2 "); |
|
438 asm("addcs r0, r0, #4 "); |
|
439 asm("ldrle r0, [r0] "); |
|
440 asm("streq r12, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr() |
|
441 asm("add r2, r12, r12 "); // size=2*length into r2 for function call |
|
442 asm("b memmove "); // call memmove |
|
443 } |
|
444 |
|
445 __NAKED__ EXPORT_C TPtr16 TDes16::LeftTPtr(TInt /*aLength*/) const |
|
446 // |
|
447 // Extract the left portion of the descriptor. |
|
448 // |
|
449 { |
|
450 // On entry r0=return store ptr, r1=this, r2=aLength |
|
451 // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr) |
|
452 asm("ldr r3, [r1], #4 "); // r3=this.length/type |
|
453 asm("cmp r2, #0 "); // check aLength>=0 |
|
454 asm("blt Des16PanicPosOutOfRange__Fv "); // if not, panic |
|
455 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
456 asm("cmp r2, r12 "); // else limit aLength to Length() |
|
457 asm("movgt r2, r12 "); |
|
458 asm("cmp r3, #0x50000000 "); |
|
459 asm("bcs Des16PanicBadDesType__Fv "); |
|
460 asm("eor r3, r3, r3, lsr #1 "); |
|
461 asm("msr cpsr_flg, r3 "); |
|
462 asm("addcs r1, r1, #4 "); |
|
463 asm("ldrle r1, [r1] "); |
|
464 asm("addeq r1, r1, #4 "); // r1=this.Ptr() |
|
465 asm("mov r3, r1 "); // r3=this.Ptr() |
|
466 asm("orr r1, r2, #0x20000000 "); // r1=aLength + EPtr |
|
467 asm("stmia r0, {r1-r3} "); |
|
468 __JUMP(,lr); |
|
469 } |
|
470 |
|
471 __NAKED__ EXPORT_C TPtr16 TDes16::RightTPtr(TInt /*aLength*/) const |
|
472 // |
|
473 // Extract the right portion of the descriptor. |
|
474 // |
|
475 { |
|
476 // On entry r0=return store ptr, r1=this, r2=aLength |
|
477 // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr) |
|
478 asm("ldr r3, [r1], #4 "); // r3=this.length/type |
|
479 asm("cmp r2, #0 "); // check aLength>=0 |
|
480 asm("blt Des16PanicPosOutOfRange__Fv "); // if not, panic |
|
481 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
482 asm("cmp r2, r12 "); // else limit aLength to Length() |
|
483 asm("movgt r2, r12 "); |
|
484 asm("cmp r3, #0x50000000 "); |
|
485 asm("bcs Des16PanicBadDesType__Fv "); |
|
486 asm("eor r3, r3, r3, lsr #1 "); |
|
487 asm("msr cpsr_flg, r3 "); |
|
488 asm("addcs r1, r1, #4 "); |
|
489 asm("ldrle r1, [r1] "); |
|
490 asm("addeq r1, r1, #4 "); // r0=this.Ptr() |
|
491 asm("add r3, r1, r12, lsl #1 "); // r3=this.Ptr()+len*2 |
|
492 asm("orr r1, r2, #0x20000000 "); // r1=aLength + EPtr |
|
493 asm("sub r3, r3, r2, lsl #1 "); // r2=Ptr()+len*2-aLength*2 |
|
494 asm("stmia r0, {r1-r3} "); |
|
495 __JUMP(,lr); |
|
496 } |
|
497 |
|
498 __NAKED__ EXPORT_C TPtr16 TDes16::MidTPtr(TInt /*aPos*/) const |
|
499 // |
|
500 // Extract the middle portion of the descriptor. |
|
501 // |
|
502 { |
|
503 // On entry r0=return store ptr, r1=this, r2=aPos |
|
504 // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr) |
|
505 asm("ldr r3, [r1], #4 "); // r3=this.length/type |
|
506 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
507 asm("cmp r2, #0 "); // check aPos>=0 |
|
508 asm("cmpge r12, r2 "); // if so check Length()>=aPos |
|
509 asm("blt Des16PanicPosOutOfRange__Fv "); |
|
510 asm("cmp r3, #0x50000000 "); |
|
511 asm("bcs Des16PanicBadDesType__Fv "); |
|
512 asm("eor r3, r3, r3, lsr #1 "); |
|
513 asm("msr cpsr_flg, r3 "); |
|
514 asm("addcs r1, r1, #4 "); |
|
515 asm("ldrle r1, [r1] "); |
|
516 asm("addeq r1, r1, #4 "); // r0=this.Ptr() |
|
517 asm("add r3, r1, r2, lsl #1 "); // r3=this.Ptr()+aPos*2 |
|
518 asm("sub r2, r12, r2 "); // r2=len-aPos (=newMaxLen) |
|
519 asm("orr r1, r2, #0x20000000 "); // r1=len-aPos + EPtr (=newLen/Type) |
|
520 asm("stmia r0, {r1-r3} "); |
|
521 __JUMP(,lr); |
|
522 } |
|
523 |
|
524 __NAKED__ EXPORT_C TPtr16 TDes16::MidTPtr(TInt /*aPos*/,TInt /*aLength*/) const |
|
525 // |
|
526 // Extract the middle portion of the descriptor. |
|
527 // |
|
528 { |
|
529 // On entry r0=return store ptr, r1=this, r2=aPos, r3=aLength |
|
530 // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr) |
|
531 asm("str r4, [sp, #-4]! "); // save r4 |
|
532 asm("ldr r12, [r1], #4 "); // r12=this.length/type |
|
533 asm("mov r4, r1 "); |
|
534 asm("cmp r12, #0x50000000 "); // check valid descriptor type |
|
535 asm("bcs Des16PanicBadDesType__Fv "); |
|
536 asm("eor r12, r12, r12, lsr #1 "); |
|
537 asm("msr cpsr_flg, r12 "); |
|
538 asm("ldr r12, [r1, #-4] "); |
|
539 asm("addcs r4, r4, #4 "); |
|
540 asm("ldrle r4, [r4] "); |
|
541 asm("bic r12, r12, #0xF0000000 "); // r12=Length() |
|
542 asm("addeq r4, r4, #4 "); // r4=this.Ptr() |
|
543 asm("cmp r2, #0 "); // check aPos>=0 |
|
544 asm("subge r12, r12, r2 "); // if so, r12=Length()-aPos |
|
545 asm("cmpge r12, r3 "); // and check Length()-aPos>=aLength |
|
546 asm("orrge r1, r3, #0x20000000 "); // if so, r0 = aLength + EPtr |
|
547 asm("addge r3, r4, r2, lsl #1 "); // and r2=this.Ptr()+aPos*2 |
|
548 asm("bicge r2, r1, #0xF0000000 "); // and r1=aLength |
|
549 asm("stmgeia r0, {r1-r3} "); |
|
550 asm("ldrge r4, [sp], #4 "); |
|
551 __JUMP(ge,lr); |
|
552 asm("b Des16PanicPosOutOfRange__Fv "); |
|
553 } |
|
554 |
|
555 __NAKED__ EXPORT_C const TUint16& TDesC16::AtC(TInt /*anIndex*/) const |
|
556 // |
|
557 // Return a reference to the character in the buffer. |
|
558 // |
|
559 { |
|
560 asm("ldr r2, [r0], #4 "); // r2=length/type |
|
561 asm("bic r3, r2, #0xF0000000 "); // r3=length |
|
562 asm("cmp r2, #0x50000000 "); |
|
563 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
564 asm("eor r2, r2, r2, lsr #1 "); |
|
565 asm("msr cpsr_flg, r2 "); |
|
566 asm("addcs r0, r0, #4 "); |
|
567 asm("ldrle r0, [r0] "); |
|
568 asm("addeq r0, r0, #4 "); // r0=this.Ptr() |
|
569 asm("cmp r1, #0 "); // check index>=0 |
|
570 asm("cmpge r3, r1 "); // if so, check Length()>index |
|
571 asm("addgt r0, r0, r1, lsl #1 "); // return value = this.Ptr()+index*2 |
|
572 __JUMP(gt,lr); |
|
573 asm("b " CSM_Z28Des16PanicDesIndexOutOfRangev); |
|
574 } |
|
575 |
|
576 #ifdef __DES16_MACHINE_CODED_HWORD__ |
|
577 __NAKED__ EXPORT_C TInt TDesC16::Locate(TChar /*aChar*/) const |
|
578 // |
|
579 // Locate character aChar in the descriptor. |
|
580 // |
|
581 { |
|
582 asm("ldr r2, [r0], #4 "); // r2=length/type |
|
583 asm("cmp r2, #0x50000000 "); |
|
584 asm("bcs Des16PanicBadDesType__Fv "); |
|
585 asm("bics r3, r2, #0xF0000000 "); // r3=length |
|
586 asm("mvneq r0, #0 "); // if length=0, not found |
|
587 __JUMP(eq,lr); |
|
588 asm("eor r2, r2, r2, lsr #1 "); |
|
589 asm("msr cpsr_flg, r2 "); |
|
590 asm("addcs r0, r0, #4 "); |
|
591 asm("ldrle r0, [r0] "); |
|
592 asm("addeq r0, r0, #4 "); // r0=this.Ptr() |
|
593 asm("add r3, r0, r3, lsl #1 "); // r3=ptr+length*2 (end of string pointer) |
|
594 asm("add r12, r0, #2 "); // r12=ptr+2 |
|
595 asm("1: "); |
|
596 asm("ldrh r2, [r0], #2 "); // r2=*r0++ |
|
597 asm("cmp r1, r2 "); // is r1=match char? |
|
598 asm("cmpne r0, r3 "); // if not, is r0=r3 (end pointer) |
|
599 asm("bne 1b "); |
|
600 asm("cmp r1, r2 "); // did we find char? |
|
601 asm("subeq r0, r0, r12 "); // if we did, return value = r0-ptr-2 |
|
602 asm("moveq r0, r0, lsr #1 "); // divide by 2 to get index |
|
603 asm("mvnne r0, #0 "); // else return value =-1 |
|
604 __JUMP(,lr); |
|
605 } |
|
606 |
|
607 __NAKED__ EXPORT_C TInt TDesC16::LocateReverse(TChar /*aChar*/) const |
|
608 // |
|
609 // Locate character aChar in the descriptor in reverse. |
|
610 // |
|
611 { |
|
612 asm("ldr r2, [r0], #4 "); // r2=length/type |
|
613 asm("cmp r2, #0x50000000 "); |
|
614 asm("bcs Des16PanicBadDesType__Fv "); |
|
615 asm("bics r3, r2, #0xF0000000 "); // r3=length |
|
616 asm("mvneq r0, #0 "); // if length=0, not found |
|
617 __JUMP(eq,lr); |
|
618 asm("eor r2, r2, r2, lsr #1 "); |
|
619 asm("msr cpsr_flg, r2 "); |
|
620 asm("addcs r0, r0, #4 "); |
|
621 asm("ldrle r0, [r0] "); |
|
622 asm("addeq r0, r0, #4 "); // r0=this.Ptr() |
|
623 asm("add r3, r0, r3, lsl #1 "); // r3=Ptr()+Length() |
|
624 asm("1: "); |
|
625 asm("ldrh r2, [r3, #-2]! "); // r2=*--r3 |
|
626 asm("cmp r1, r2 "); // is r1=match char? |
|
627 asm("cmpne r3, r0 "); // if not, have we reached beginning of string? |
|
628 asm("bne 1b "); // loop if neither |
|
629 asm("cmp r1, r2 "); // did we find match char? |
|
630 asm("subeq r0, r3, r0 "); // if we did, return value = (r3-r0)/2 |
|
631 asm("moveq r0, r0, lsr #1 "); |
|
632 asm("mvnne r0, #0 "); // else return value =-1 |
|
633 __JUMP(,lr); |
|
634 } |
|
635 #endif |
|
636 |
|
637 #ifndef __KERNEL_MODE__ |
|
638 __NAKED__ EXPORT_C TInt TDesC16::CompareF(const TDesC16& /*aDes*/) const |
|
639 // |
|
640 // Compare a descriptor to this descriptor folded. |
|
641 // |
|
642 { |
|
643 asm("ldr r12, 1f "); |
|
644 asm("b comparebody "); |
|
645 asm("1: "); |
|
646 asm(".word " CSM_ZN3Mem8CompareFEPKtiS0_i); |
|
647 } |
|
648 |
|
649 __NAKED__ EXPORT_C TInt TDesC16::CompareC(const TDesC16& /*aDes*/) const |
|
650 // |
|
651 // Compare a descriptor to this descriptor collated. |
|
652 // |
|
653 { |
|
654 asm("ldr r12, 1f "); |
|
655 asm("b comparebody "); |
|
656 asm("1: "); |
|
657 asm(".word " CSM_ZN3Mem8CompareCEPKtiS0_i); |
|
658 } |
|
659 #endif |
|
660 |
|
661 __NAKED__ EXPORT_C TInt TDesC16::Compare(const TDesC16& /*aDes*/) const |
|
662 // |
|
663 // Compare a descriptor to this descriptor. |
|
664 // |
|
665 { |
|
666 asm("ldr r12, 1f "); |
|
667 asm("comparebody: "); |
|
668 asm("mov r2, r1 "); // r2=&aDes |
|
669 asm("ldr r3, [r0], #4 "); // r3=this.length/type |
|
670 asm("cmp r3, #0x50000000 "); |
|
671 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
672 asm("bic r1, r3, #0xF0000000 "); // r1=this.Length() |
|
673 asm("eor r3, r3, r3, lsr #1 "); |
|
674 asm("msr cpsr_flg, r3 "); |
|
675 asm("addcs r0, r0, #4 "); |
|
676 asm("ldrle r0, [r0] "); |
|
677 asm("addeq r0, r0, #4 "); // r0=this.Ptr() |
|
678 asm("ldr r3, [r2], #4 "); // r3=aDes.length/type |
|
679 asm("cmp r3, #0x50000000 "); |
|
680 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
681 asm("eor r3, r3, r3, lsr #1 "); |
|
682 asm("msr cpsr_flg, r3 "); |
|
683 asm("ldr r3, [r2, #-4] "); |
|
684 asm("bic r3, r3, #0xF0000000 "); // r3=aDes.Length() |
|
685 asm("addcs r2, r2, #4 "); |
|
686 asm("ldrle r2, [r2] "); |
|
687 asm("addeq r2, r2, #4 "); // r2=aDes.Ptr() |
|
688 #ifdef __KERNEL_MODE__ |
|
689 asm("add r1, r1, r1 "); |
|
690 asm("add r3, r3, r3 "); |
|
691 #endif |
|
692 __JUMP(,r12); |
|
693 |
|
694 asm("1: "); |
|
695 #ifdef __KERNEL_MODE__ |
|
696 asm(".word memcompare "); |
|
697 #else |
|
698 asm(".word " CSM_ZN3Mem7CompareEPKtiS0_i); |
|
699 #endif |
|
700 } |
|
701 #endif // __DES16_MACHINE_CODED__ |
|
702 |
|
703 |
|
704 #if defined(__DES16_MACHINE_CODED__) && !defined(__EABI__) |
|
705 __NAKED__ EXPORT_C TPtrC16 TDesC16::Left(TInt /*aLength*/) const |
|
706 // |
|
707 // Extract the left portion of the descriptor. |
|
708 // |
|
709 { |
|
710 // On entry r0=this, r1=aLength |
|
711 // Return TPtrC16 in r0,r1 |
|
712 asm("ldr r3, [r0], #4 "); // r3=this.length/type |
|
713 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
714 asm("cmp r1, #0 "); // check aLength>=0 |
|
715 asm("blt " CSM_Z23Des16PanicPosOutOfRangev); // if not, panic |
|
716 asm("cmp r1, r12 "); // else limit aLength to Length() |
|
717 asm("movgt r1, r12 "); |
|
718 asm("cmp r3, #0x50000000 "); |
|
719 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
720 asm("eor r3, r3, r3, lsr #1 "); |
|
721 asm("msr cpsr_flg, r3 "); |
|
722 asm("addcs r0, r0, #4 "); |
|
723 asm("ldrle r0, [r0] "); |
|
724 asm("addeq r0, r0, #4 "); // r0=this.Ptr() |
|
725 asm("orr r2, r1, #0x10000000 "); // r2=aLength + EPtrC |
|
726 asm("mov r1, r0 "); // r1=result ptr |
|
727 asm("mov r0, r2 "); // r0=result type/length |
|
728 __JUMP(,lr); |
|
729 } |
|
730 |
|
731 __NAKED__ EXPORT_C TPtrC16 TDesC16::Right(TInt /*aLength*/) const |
|
732 // |
|
733 // Extract the right portion of the descriptor. |
|
734 // |
|
735 { |
|
736 // On entry r0=this, r1=aLength |
|
737 // Return TPtrC16 in r0,r1 |
|
738 asm("ldr r3, [r0], #4 "); // r3=this.length/type |
|
739 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
740 asm("cmp r1, #0 "); // check aLength>=0 |
|
741 asm("blt " CSM_Z23Des16PanicPosOutOfRangev); // if not, panic |
|
742 asm("cmp r1, r12 "); // else limit aLength to Length() |
|
743 asm("movgt r1, r12 "); |
|
744 asm("cmp r3, #0x50000000 "); |
|
745 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
746 asm("eor r3, r3, r3, lsr #1 "); |
|
747 asm("msr cpsr_flg, r3 "); |
|
748 asm("addcs r0, r0, #4 "); |
|
749 asm("ldrle r0, [r0] "); |
|
750 asm("addeq r0, r0, #4 "); // r0=this.Ptr() |
|
751 asm("add r3, r0, r12, lsl #1 "); // r3=this.Ptr()+len*2 |
|
752 asm("orr r0, r1, #0x10000000 "); // r0=aLength + EPtrC |
|
753 asm("sub r1, r3, r1, lsl #1 "); // r1=Ptr()+len*2-aLength*2 |
|
754 __JUMP(,lr); |
|
755 } |
|
756 |
|
757 __NAKED__ EXPORT_C TPtrC16 TDesC16::Mid(TInt /*aPos*/) const |
|
758 // |
|
759 // Extract the middle portion of the descriptor. |
|
760 // |
|
761 { |
|
762 // On entry r0=this, r1=aPos |
|
763 // Return TPtrC16 in r0,r1 |
|
764 asm("ldr r3, [r0], #4 "); // r3=this.length/type |
|
765 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
766 asm("cmp r1, #0 "); // check aPos>=0 |
|
767 asm("cmpge r12, r1 "); // if so check Length()>=aPos |
|
768 asm("blt " CSM_Z23Des16PanicPosOutOfRangev); |
|
769 asm("cmp r3, #0x50000000 "); |
|
770 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
771 asm("eor r3, r3, r3, lsr #1 "); |
|
772 asm("msr cpsr_flg, r3 "); |
|
773 asm("addcs r0, r0, #4 "); |
|
774 asm("ldrle r0, [r0] "); |
|
775 asm("addeq r0, r0, #4 "); // r0=this.Ptr() |
|
776 asm("sub r2, r12, r1 "); // r2=len-aPos |
|
777 asm("add r1, r0, r1, lsl #1 "); // r1=this.Ptr()+aPos*2 |
|
778 asm("orr r0, r2, #0x10000000 "); // r0=result length + EPtrC |
|
779 __JUMP(,lr); |
|
780 } |
|
781 |
|
782 __NAKED__ EXPORT_C TPtrC16 TDesC16::Mid(TInt /*aPos*/,TInt /*aLength*/) const |
|
783 // |
|
784 // Extract the middle portion of the descriptor. |
|
785 // |
|
786 { |
|
787 // On entry r0=this, r1=aPos, r2=aLength |
|
788 // Return TPtrC16 in r0,r1 |
|
789 asm("ldr r12, [r0], #4 "); // r12=this.length/type |
|
790 asm("cmp r12, #0x50000000 "); // check valid descriptor type |
|
791 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
792 asm("eor r12, r12, r12, lsr #1 "); |
|
793 asm("msr cpsr_flg, r12 "); |
|
794 asm("ldr r12, [r0, #-4] "); |
|
795 asm("bic r12, r12, #0xF0000000 "); // r12=Length() |
|
796 asm("addcs r0, r0, #4 "); |
|
797 asm("ldrle r0, [r0] "); |
|
798 asm("addeq r0, r0, #4 "); // r0=this.Ptr() |
|
799 asm("cmp r1, #0 "); // check aPos>=0 |
|
800 asm("subge r12, r12, r1 "); // if so, r12=Length()-aPos |
|
801 asm("cmpge r12, r2 "); // and check Length()-aPos>=aLength |
|
802 asm("addge r1, r0, r1, lsl #1 "); // if so, r1=Ptr()+aPos*2 |
|
803 asm("orrge r0, r2, #0x10000000 "); // and r0 = aLength + EPtrC |
|
804 __JUMP(ge,lr); |
|
805 asm("b " CSM_Z23Des16PanicPosOutOfRangev); |
|
806 } |
|
807 #endif // defined(__DES16_MACHINE_CODED__) && !defined(__EABI__) |
|
808 |
|
809 |
|
810 #ifdef __DES16_MACHINE_CODED__ |
|
811 |
|
812 // Here are the __EABI__ compliant versions of the above |
|
813 #ifdef __EABI__ |
|
814 __NAKED__ EXPORT_C TPtrC16 TDesC16::Left(TInt /*aLength*/) const |
|
815 // |
|
816 // Extract the left portion of the descriptor. |
|
817 // |
|
818 { |
|
819 // On entry r0=return store ptr, r1=this, r2=aLength |
|
820 // Return TPtr16 ([r0]=length/type,[r0,#4]=Ptr) |
|
821 asm("ldr r3, [r1], #4 "); // r3=this.length/type |
|
822 asm("cmp r2, #0 "); // check aLength>=0 |
|
823 asm("blt Des16PanicPosOutOfRange__Fv "); // if not, panic |
|
824 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
825 asm("cmp r2, r12 "); // else limit aLength to Length() |
|
826 asm("movgt r2, r12 "); |
|
827 asm("cmp r3, #0x50000000 "); |
|
828 asm("bcs Des16PanicBadDesType__Fv "); |
|
829 asm("eor r3, r3, r3, lsr #1 "); |
|
830 asm("msr cpsr_flg, r3 "); |
|
831 asm("addcs r1, r1, #4 "); |
|
832 asm("ldrle r1, [r1] "); |
|
833 asm("addeq r1, r1, #4 "); // r1=this.Ptr() |
|
834 asm("mov r3, r1"); // r3=this.Ptr() |
|
835 asm("orr r1, r2, #0x10000000 "); // r1=aLength + EPtrC |
|
836 asm("stmia r0, {r1,r3} "); |
|
837 __JUMP(,lr); |
|
838 } |
|
839 |
|
840 __NAKED__ EXPORT_C TPtrC16 TDesC16::Right(TInt /*aLength*/) const |
|
841 // |
|
842 // Extract the right portion of the descriptor. |
|
843 // |
|
844 { |
|
845 // On entry r0=return store ptr, r1=this, r2=aLength |
|
846 // Return TPtr16 ([r0]=length/type,[r0,#4]=Ptr) |
|
847 asm("ldr r3, [r1], #4 "); // r3=this.length/type |
|
848 asm("cmp r2, #0 "); // check aLength>=0 |
|
849 asm("blt Des16PanicPosOutOfRange__Fv "); // if not, panic |
|
850 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
851 asm("cmp r2, r12 "); // else limit aLength to Length() |
|
852 asm("movgt r2, r12 "); |
|
853 asm("cmp r3, #0x50000000 "); |
|
854 asm("bcs Des16PanicBadDesType__Fv "); |
|
855 asm("eor r3, r3, r3, lsr #1 "); |
|
856 asm("msr cpsr_flg, r3 "); |
|
857 asm("addcs r1, r1, #4 "); |
|
858 asm("ldrle r1, [r1] "); |
|
859 asm("addeq r1, r1, #4 "); // r1=this.Ptr() |
|
860 asm("add r3, r1, r12, lsl #1 "); // r3=this.Ptr()+len*2 |
|
861 asm("orr r1, r2, #0x10000000 "); // r1=aLength + EPtrC |
|
862 asm("sub r3, r3, r2, lsl #1 "); // r2=Ptr()+len*2-aLength*2 |
|
863 asm("stmia r0, {r1,r3} "); |
|
864 __JUMP(,lr); |
|
865 } |
|
866 |
|
867 __NAKED__ EXPORT_C TPtrC16 TDesC16::Mid(TInt /*aPos*/) const |
|
868 // |
|
869 // Extract the middle portion of the descriptor. |
|
870 // |
|
871 { |
|
872 // On entry r0=return store ptr, r1=this, r2=aPos |
|
873 // Return TPtr16 ([r0]=length/type,[r0,#4]=Ptr) |
|
874 asm("ldr r3, [r1], #4 "); // r3=this.length/type |
|
875 asm("bic r12, r3, #0xF0000000 "); // r12=this.Length() |
|
876 asm("cmp r2, #0 "); // check aPos>=0 |
|
877 asm("cmpge r12, r2 "); // if so check Length()>=aPos |
|
878 asm("blt Des16PanicPosOutOfRange__Fv "); |
|
879 asm("cmp r3, #0x50000000 "); |
|
880 asm("bcs Des16PanicBadDesType__Fv "); |
|
881 asm("eor r3, r3, r3, lsr #1 "); |
|
882 asm("msr cpsr_flg, r3 "); |
|
883 asm("addcs r1, r1, #4 "); |
|
884 asm("ldrle r1, [r1] "); |
|
885 asm("addeq r1, r1, #4 "); // r3=this.Ptr() |
|
886 asm("add r3, r1, r2, lsl #1 "); // r3=this.Ptr()+aPos*2 |
|
887 asm("sub r2, r12, r2 "); // r2=len-aPos (=newMaxLen) |
|
888 asm("orr r1, r2, #0x10000000 "); // r1=len-aPos + EPtrC (=newLen/Type) |
|
889 asm("stmia r0, {r1,r3} "); |
|
890 __JUMP(,lr); |
|
891 } |
|
892 |
|
893 __NAKED__ EXPORT_C TPtrC16 TDesC16::Mid(TInt /*aPos*/,TInt /*aLength*/) const |
|
894 // |
|
895 // Extract the middle portion of the descriptor. |
|
896 // |
|
897 { |
|
898 // On entry r0=return store ptr, r1=this, r2=aPos, r3=aLength |
|
899 // Return TPtr16 ([r0]=length/type,[r0,#4]=Ptr) |
|
900 asm("ldr r12, [r1], #4 "); // r12=this.length/type |
|
901 asm("cmp r12, #0x50000000 "); // check valid descriptor type |
|
902 asm("bcs Des16PanicBadDesType__Fv "); |
|
903 asm("eor r12, r12, r12, lsr #1 "); |
|
904 asm("msr cpsr_flg, r12 "); |
|
905 asm("ldr r12, [r1, #-4] "); |
|
906 asm("addcs r1, r1, #4 "); |
|
907 asm("ldrle r1, [r1] "); |
|
908 asm("bic r12, r12, #0xF0000000 "); // r12=Length() |
|
909 asm("addeq r1, r1, #4 "); // r1=this.Ptr() |
|
910 asm("cmp r2, #0 "); // check aPos>=0 |
|
911 asm("subge r12, r12, r2 "); // if so, r12=Length()-aPos |
|
912 asm("cmpge r12, r3 "); // and check Length()-aPos>=aLength |
|
913 asm("addge r2, r1, r2, lsl #1 "); // if so r2=this.Ptr()+aPos*2 |
|
914 asm("orrge r1, r3, #0x10000000 "); // and r1 = aLength + EPtrC |
|
915 asm("stmgeia r0, {r1,r2} "); |
|
916 __JUMP(ge,lr); |
|
917 asm("b Des16PanicPosOutOfRange__Fv "); |
|
918 } |
|
919 #endif // __EABI__ |
|
920 |
|
921 |
|
922 __NAKED__ EXPORT_C void TDes16::Zero() |
|
923 // |
|
924 // Zero the buffer. |
|
925 // |
|
926 { |
|
927 asm("ldr r1, [r0] "); // r1=length/type |
|
928 asm("and r1, r1, #0xF0000000 "); // r1=type field, zero length |
|
929 asm("cmp r1, #0x40000000 "); // check for EBufCPtr |
|
930 asm("str r1, [r0] "); // store zero length |
|
931 __JUMP(ne,lr); |
|
932 asm("ldr r2, [r0, #8] "); // r2 = pointer to TBufCBase |
|
933 asm("mov r1, #0 "); |
|
934 asm("str r1, [r2] "); // update length of TBufCBase |
|
935 __JUMP(,lr); |
|
936 } |
|
937 |
|
938 #ifdef __DES16_MACHINE_CODED_HWORD__ |
|
939 #ifndef __KERNEL_MODE__ |
|
940 __NAKED__ EXPORT_C void TDes16::ZeroTerminate() |
|
941 // |
|
942 // Zero terminate at Length(). |
|
943 // |
|
944 { |
|
945 // Fall though to PtrZ below... |
|
946 } |
|
947 |
|
948 __NAKED__ EXPORT_C const TUint16* TDes16::PtrZ() |
|
949 // |
|
950 // Return a pointer to a 0 terminated string. |
|
951 // |
|
952 { |
|
953 asm("ldmia r0, {r1,r2} "); // r1=length/type, r2=maxlength |
|
954 asm("bic r3, r1, #0xF0000000 "); // r3=Length(); |
|
955 asm("cmp r3, r2 "); // check Length()<MaxLength() |
|
956 asm("bge Des16PanicDesOverflow__Fv "); |
|
957 asm("cmp r1, #0x50000000 "); |
|
958 asm("bcs Des16PanicBadDesType__Fv "); |
|
959 asm("eor r1, r1, r1, lsr #1 "); |
|
960 asm("msr cpsr_flg, r1 "); |
|
961 asm("add r0, r0, #4 "); |
|
962 asm("addcs r0, r0, #4 "); |
|
963 asm("ldrle r0, [r0] "); |
|
964 asm("addeq r0, r0, #4 "); // r0=Ptr() |
|
965 asm("add r1, r0, r3, lsl #1 "); // r1=Ptr()+Length() |
|
966 asm("mov r2, #0 "); |
|
967 asm("strh r2, [r1] "); // Ptr()[Length()]=0; |
|
968 __JUMP(,lr); |
|
969 } |
|
970 #endif // __KERNEL_MODE__ |
|
971 |
|
972 __NAKED__ EXPORT_C void TDes16::Append(TChar /*aChar*/) |
|
973 // |
|
974 // Add a character at the end of the string. |
|
975 // |
|
976 { |
|
977 asm("ldmia r0, {r2,r3} "); // r2=length/type, r3=maxlength |
|
978 asm("bic r12, r2, #0xF0000000 "); // r12=Length(); |
|
979 asm("cmp r12, r3 "); // check Length()<MaxLength() |
|
980 asm("bge Des16PanicDesOverflow__Fv "); |
|
981 asm("cmp r2, #0x50000000 "); |
|
982 asm("bcs Des16PanicBadDesType__Fv "); |
|
983 asm("add r2, r2, #1 "); // increment length by 1 |
|
984 asm("str r2, [r0] "); // store new length |
|
985 asm("eor r2, r2, r2, lsr #1 "); |
|
986 asm("msr cpsr_flg, r2 "); |
|
987 asm("add r2, r0, #4 "); // r2=this+4 |
|
988 asm("addcs r2, r2, #4 "); |
|
989 asm("ldrle r2, [r2] "); |
|
990 asm("addeq r3, r12, #1 "); // if EBufCPtr, r3=Length()+1 |
|
991 asm("streq r3, [r2], #4 "); // and update length of TBufCBase, r2=Ptr() |
|
992 asm("add r2, r2, r12, lsl #1 "); // r2=Ptr()+Length() |
|
993 asm("strh r1, [r2] "); // Ptr()[Length()]=aChar; |
|
994 __JUMP(,lr); |
|
995 } |
|
996 #endif |
|
997 |
|
998 __NAKED__ EXPORT_C void TDes16::Append(const TDesC16& /*aDes*/) |
|
999 // |
|
1000 // Append a descriptor to this descriptor. |
|
1001 // |
|
1002 { |
|
1003 asm("ldr r3, [r1], #4 "); // r3=aDes.length/type |
|
1004 asm("cmp r3, #0x50000000 "); |
|
1005 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
1006 asm("bics r2, r3, #0xF0000000 "); // r2=aDes.Length() |
|
1007 __JUMP(eq,lr); |
|
1008 asm("eor r3, r3, r3, lsr #1 "); |
|
1009 asm("msr cpsr_flg, r3 "); |
|
1010 asm("addcs r1, r1, #4 "); |
|
1011 asm("ldrle r1, [r1] "); |
|
1012 asm("addeq r1, r1, #4 "); // r1=aDes.Ptr() |
|
1013 asm("b appendbody "); // use following routine for rest of job |
|
1014 } |
|
1015 |
|
1016 __NAKED__ EXPORT_C void TDes16::Append(const TUint16* /*aBuf*/,TInt /*aLength*/) |
|
1017 // |
|
1018 // Append aLength from aBuf characters to the descriptor. |
|
1019 // |
|
1020 { |
|
1021 asm("cmp r2, #0 "); // check aLength>=0 |
|
1022 __JUMP(eq,lr); |
|
1023 asm("blt " CSM_Z24Des16PanicLengthNegativev); |
|
1024 asm("appendbody: "); |
|
1025 asm("ldmia r0, {r3,r12} "); // r3=type/length, r12=maxlength |
|
1026 asm("cmp r3, #0x50000000 "); |
|
1027 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
1028 asm("bic r3, r3, #0xF0000000 "); // r3=Length() |
|
1029 asm("sub r12, r12, r3 "); // r12=MaxLength-Length |
|
1030 asm("cmp r2, r12 "); // check aLength<=(MaxLength-Length) |
|
1031 asm("bgt " CSM_Z21Des16PanicDesOverflowv); |
|
1032 asm("ldr r12, [r0] "); |
|
1033 asm("add r12, r12, r2 "); // new length/type field |
|
1034 asm("str r12, [r0], #4 "); // store it |
|
1035 asm("eor r12, r12, r12, lsr #1 "); |
|
1036 asm("msr cpsr_flg, r12 "); |
|
1037 asm("addcs r0, r0, #4 "); |
|
1038 asm("ldrle r0, [r0] "); |
|
1039 asm("ldreq r12, [r0] "); // fetch length from TBufCBase |
|
1040 asm("addeq r12, r12, r2 "); // add aLength |
|
1041 asm("streq r12, [r0], #4 "); // update length of TBufCBase, r0=Ptr() |
|
1042 asm("add r0, r0, r3, lsl #1 "); // r0=Ptr()+Length()*2 |
|
1043 asm("add r2, r2, r2 "); // r2=aLength*2 |
|
1044 asm("b memmove "); // call memmove |
|
1045 } |
|
1046 |
|
1047 __NAKED__ EXPORT_C void TDes16::FillZ() |
|
1048 // |
|
1049 // Fill the descriptor with 0. |
|
1050 // |
|
1051 { |
|
1052 asm("ldr r2, [r0] "); // r2=length/type |
|
1053 asm("cmp r2, #0x50000000 "); |
|
1054 asm("bcs " CSM_Z20Des16PanicBadDesTypev); |
|
1055 asm("bic r1, r2, #0xF0000000 "); // r1=Length() |
|
1056 asm("eor r2, r2, r2, lsr #1 "); |
|
1057 asm("msr cpsr_flg, r2 "); |
|
1058 asm("add r0, r0, #4 "); |
|
1059 asm("addcs r0, r0, #4 "); |
|
1060 asm("ldrle r0, [r0] "); |
|
1061 asm("addeq r0, r0, #4 "); // r0=Ptr() |
|
1062 asm("add r1, r1, r1 "); // r1=2*Length() |
|
1063 asm("b memclr "); // call memclr |
|
1064 } |
|
1065 |
|
1066 #ifdef __DES16_MACHINE_CODED_HWORD__ |
|
1067 __NAKED__ EXPORT_C void TDes16::Fill(TChar /*aChar*/) |
|
1068 // |
|
1069 // Fill the descriptor with aChar. |
|
1070 // |
|
1071 { |
|
1072 // on entry r0=this, r1=fill char |
|
1073 asm("ldr r3, [r0] "); // r3=length/type |
|
1074 asm("cmp r3, #0x50000000 "); |
|
1075 asm("bcs Des16PanicBadDesType__Fv "); |
|
1076 asm("bics r2, r3, #0xF0000000 "); // r2=Length() |
|
1077 __JUMP(eq,lr); // if length is zero, finished |
|
1078 asm("stmfd sp!, {r0,lr} "); // save registers for function call |
|
1079 asm("eor r3, r3, r3, lsr #1 "); |
|
1080 asm("msr cpsr_flg, r3 "); |
|
1081 asm("add r0, r0, #4 "); |
|
1082 asm("addcs r0, r0, #4 "); |
|
1083 asm("ldrle r0, [r0] "); |
|
1084 asm("addeq r0, r0, #4 "); // r0=Ptr() |
|
1085 asm("tst r0, #2 "); // check alignment of Ptr() |
|
1086 asm("strneh r1, [r0], #2 "); // if not aligned, fill first location |
|
1087 asm("subne r2, r2, #1 "); // and decrement length |
|
1088 asm("mov r1, r1, lsl #16 "); |
|
1089 asm("orr r1, r1, r1, lsr #16 "); // r1=fill char repeated |
|
1090 asm("mov r3, r1 "); |
|
1091 asm("mov r12, r1 "); |
|
1092 asm("mov r14, r1 "); // r1=r3=r12=r14=fill char repeated |
|
1093 asm("b 2f "); // branch to check for 16-char blocks |
|
1094 asm("1: "); |
|
1095 asm("stmia r0!, {r1,r3,r12,r14} "); // fill a block of 16 bytes |
|
1096 asm("stmia r0!, {r1,r3,r12,r14} "); // fill a block of 16 bytes |
|
1097 asm("2: "); |
|
1098 asm("subs r2, r2, #16 "); // check for more blocks of 16 |
|
1099 asm("bge 1b "); // loop if more |
|
1100 asm("add r2, r2, #16 "); // now r1=number of chars remaining, 0<=r1<16 |
|
1101 asm("mov r2, r2, lsl #28 "); // move into bits 28-31 |
|
1102 asm("msr cpsr_flg, r2 "); // and into NZCV flags |
|
1103 asm("stmmiia r0!, {r1,r3,r12,r14} "); // fill a block of 16 bytes if needed |
|
1104 asm("stmeqia r0!, {r1,r3} "); // fill a block of 8 bytes if needed |
|
1105 asm("stmcsia r0!, {r1} "); // fill a block of 4 bytes if needed |
|
1106 asm("strvsh r1, [r0], #2 "); // fill last char if needed |
|
1107 __POPRET("r0,"); |
|
1108 } |
|
1109 #endif |
|
1110 |
|
1111 #endif // __DES16_MACHINE_CODED__ |
|
1112 |
|
1113 |
|
1114 |
|
1115 |