1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/common/arm/cdes16.cia Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1115 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\common\arm\cdes16.cia
1.18 +//
1.19 +//
1.20 +
1.21 +#include <e32cia.h>
1.22 +#include "../common.h"
1.23 +
1.24 +#if defined(__DES16_MACHINE_CODED__) || defined(__EABI__)
1.25 +
1.26 +GLREF_C void Des16PanicBadDesType();
1.27 +GLREF_C void Des16PanicPosOutOfRange();
1.28 +
1.29 +#endif
1.30 +
1.31 +#ifdef __DES16_MACHINE_CODED__
1.32 +
1.33 +GLREF_C void Des16PanicLengthNegative();
1.34 +GLREF_C void Des16PanicMaxLengthNegative();
1.35 +GLREF_C void Des16PanicLengthOutOfRange();
1.36 +GLREF_C void Des16PanicDesOverflow();
1.37 +GLREF_C void Des16PanicDesIndexOutOfRange();
1.38 +
1.39 +__NAKED__ EXPORT_C const TUint16 *TDesC16::Ptr() const
1.40 +//
1.41 +// Return a pointer to the buffer.
1.42 +//
1.43 + {
1.44 + asm("ldr r1, [r0], #4 ");
1.45 + asm("cmp r1, #0x50000000 ");
1.46 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.47 + asm("eor r1, r1, r1, lsr #1 ");
1.48 + asm("msr cpsr_flg, r1 ");
1.49 + asm("addcs r0, r0, #4 ");
1.50 + asm("ldrle r0, [r0] ");
1.51 + asm("addeq r0, r0, #4 ");
1.52 + __JUMP(,lr);
1.53 + }
1.54 +
1.55 +#ifndef __EABI_CTORS__
1.56 +__NAKED__ EXPORT_C TPtrC16::TPtrC16()
1.57 +//
1.58 +// Default constructor
1.59 +//
1.60 + {
1.61 + asm("mov r1, #0x10000000 "); // type=EPtrC, length=0
1.62 + asm("mov r2, #0 "); // ptr=NULL
1.63 + asm("stmia r0, {r1,r2} ");
1.64 + __JUMP(,lr);
1.65 + }
1.66 +
1.67 +__NAKED__ EXPORT_C TPtrC16::TPtrC16(const TDesC16& /*aDes*/)
1.68 +//
1.69 +// Constructor
1.70 +//
1.71 + {
1.72 + asm("ldr r2, [r1], #4 "); // r2 = type/length
1.73 + asm("bic r3, r2, #0xF0000000"); // r3 = length
1.74 + asm("orr r3, r3, #0x10000000"); // r3 = EPtrC + length
1.75 + asm("cmp r2, #0x50000000 ");
1.76 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.77 + asm("eor r2, r2, r2, lsr #1 ");
1.78 + asm("msr cpsr_flg, r2 ");
1.79 + asm("addcs r1, r1, #4 ");
1.80 + asm("ldrle r1, [r1] ");
1.81 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.82 + asm("str r3, [r0] ");
1.83 + asm("str r1, [r0, #4] ");
1.84 + __JUMP(,lr);
1.85 + }
1.86 +
1.87 +#ifdef __DES16_MACHINE_CODED_HWORD__
1.88 +__NAKED__ EXPORT_C TPtrC16::TPtrC16(const TUint16* /*aString*/)
1.89 +//
1.90 +// Constructor
1.91 +//
1.92 + {
1.93 + asm("mov r2, r1 "); // save aString address
1.94 + asm("1: ");
1.95 + asm("ldrh r3, [r1], #2 ");
1.96 + asm("cmp r3, #0 ");
1.97 + asm("bne 1b "); // loop until we reach zero terminator
1.98 + asm("rsb r1, r2, r1 "); // r1 = 2*length + 2
1.99 + asm("sub r1, r1, #2 "); // r1 = 2*length
1.100 + asm("mov r1, r1, lsr #1 "); // r1 = length
1.101 + asm("orr r1, r1, #0x10000000 "); // r1=EPtrC + length
1.102 + asm("stmia r0, {r1, r2} "); // store type/length and ptr fields
1.103 + __JUMP(,lr);
1.104 + }
1.105 +#endif
1.106 +
1.107 +__NAKED__ EXPORT_C TPtrC16::TPtrC16(const TUint16* /*aBuf*/,TInt /*aLength*/)
1.108 +//
1.109 +// Constructor
1.110 +//
1.111 + {
1.112 + asm("orrs r2, r2, #0x10000000 ");
1.113 + asm("strpl r2, [r0] ");
1.114 + asm("strpl r1, [r0, #4] ");
1.115 + __JUMP(pl,lr);
1.116 + asm("b " CSM_Z24Des16PanicLengthNegativev);
1.117 + }
1.118 +
1.119 +__NAKED__ EXPORT_C TPtr16::TPtr16(TUint16* /*aBuf*/,TInt /*aMaxLength*/)
1.120 +//
1.121 +// Constructor
1.122 +//
1.123 + {
1.124 + asm("cmp r2, #0 ");
1.125 + asm("movpl r3, r1 ");
1.126 + asm("movpl r1, #0x20000000 "); // length=0, EPtr
1.127 + asm("stmplia r0, {r1,r2,r3} ");
1.128 + __JUMP(pl,lr);
1.129 + asm("b " CSM_Z27Des16PanicMaxLengthNegativev);
1.130 + }
1.131 +
1.132 +__NAKED__ EXPORT_C TPtr16::TPtr16(TUint16* /*aBuf*/,TInt /*aLength*/,TInt /*aMaxLength*/)
1.133 +//
1.134 +// Constructor
1.135 +//
1.136 + {
1.137 + asm("cmp r2, #0 "); // check length>=0
1.138 + asm("cmpge r3, r2 "); // if so, check maxlength>=length
1.139 + asm("movge r12, r1 ");
1.140 + asm("orrge r2, r2, #0x20000000 "); // r2 = length + EPtr
1.141 + asm("stmgeia r0, {r2,r3,r12} ");
1.142 + __JUMP(ge,lr);
1.143 + asm("cmp r2, #0 ");
1.144 + asm("bmi " CSM_Z24Des16PanicLengthNegativev);
1.145 + asm("cmp r3, #0 ");
1.146 + asm("bmi " CSM_Z27Des16PanicMaxLengthNegativev);
1.147 + asm("b " CSM_Z26Des16PanicLengthOutOfRangev);
1.148 + }
1.149 +
1.150 +__NAKED__ EXPORT_C TPtr16::TPtr16(TBufCBase16& /*aLcb*/,TInt /*aMaxLength*/)
1.151 +//
1.152 +// Constructor
1.153 +//
1.154 + {
1.155 + asm("mov r3, r1 ");
1.156 + asm("ldr r1, [r3] ");
1.157 + asm("bic r1, r1, #0xF0000000 "); // r1=aLcb.Length()
1.158 + asm("cmp r1, r2 "); // check against maxlength
1.159 + asm("orrle r1, r1, #0x40000000 "); // r1=aLcb.Length() + EBufCPtr
1.160 + asm("stmleia r0, {r1,r2,r3} ");
1.161 + __JUMP(le,lr);
1.162 + asm("b " CSM_Z26Des16PanicLengthOutOfRangev);
1.163 + }
1.164 +
1.165 +__NAKED__ EXPORT_C TBufCBase16::TBufCBase16()
1.166 +//
1.167 +// Constructor
1.168 +//
1.169 + {
1.170 + asm("mov r1, #0 ");
1.171 + asm("str r1, [r0] ");
1.172 + __JUMP(,lr);
1.173 + }
1.174 +
1.175 +#ifdef __DES16_MACHINE_CODED_HWORD__
1.176 +__NAKED__ EXPORT_C TBufCBase16::TBufCBase16(const TUint16* /*aString*/,TInt /*aMaxLength*/)
1.177 +//
1.178 +// Constructor
1.179 +//
1.180 + {
1.181 + asm("sub r3, r1, #2 "); // r3=aString address-2
1.182 + asm("1: ");
1.183 + asm("ldrh r12, [r3, #2]! ");
1.184 + asm("cmp r12, #0 ");
1.185 + asm("bne 1b "); // loop until we reach zero terminator
1.186 + asm("sub r3, r3, r1 "); // r3 = 2*length
1.187 + asm("mov r3, r3, lsr #1 "); // r3 = length (+EBufC)
1.188 + asm("cmp r3, r2 "); // check against max length
1.189 + asm("bgt Des16PanicLengthOutOfRange__Fv ");
1.190 + asm("stmfd sp!, {r0,lr} "); // save registers for function call
1.191 + asm("str r3, [r0], #4 "); // save length/type field, r0->buffer
1.192 + asm("add r2, r3, r3 "); // size=2*length into r2 for function call
1.193 + asm("bl memmove "); // call memmove
1.194 + __POPRET("r0,");
1.195 + }
1.196 +#endif
1.197 +
1.198 +__NAKED__ EXPORT_C TBufCBase16::TBufCBase16(const TDesC16& /*aDes*/,TInt /*aMaxLength*/)
1.199 +//
1.200 +// Constructor
1.201 +//
1.202 + {
1.203 + asm("ldr r3, [r1], #4 "); // r3 = type/length
1.204 + asm("bic r12, r3, #0xF0000000"); // r12 = length
1.205 + asm("cmp r12, r2 "); // compare with maxlength
1.206 + asm("bgt " CSM_Z26Des16PanicLengthOutOfRangev);
1.207 + asm("cmp r3, #0x50000000 ");
1.208 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.209 + asm("eor r3, r3, r3, lsr #1 ");
1.210 + asm("msr cpsr_flg, r3 ");
1.211 + asm("addcs r1, r1, #4 ");
1.212 + asm("ldrle r1, [r1] ");
1.213 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.214 + asm("stmfd sp!, {r0,lr} "); // save registers for function call
1.215 + asm("str r12, [r0], #4 "); // store length/type, r0->buffer
1.216 + asm("add r2, r12, r12 "); // size=2*length into r2 for function call
1.217 + asm("bl memmove "); // call memmove
1.218 + __POPRET("r0,");
1.219 + }
1.220 +#endif
1.221 +
1.222 +#ifdef __DES16_MACHINE_CODED_HWORD__
1.223 +__NAKED__ EXPORT_C void TBufCBase16::Copy(const TUint16* /*aString*/,TInt /*aMaxLength*/)
1.224 +//
1.225 +// Copy from a string.
1.226 +//
1.227 + {
1.228 + asm("sub r3, r1, #2 "); // r3=aString address-2
1.229 + asm("1: ");
1.230 + asm("ldrh r12, [r3, #2]! ");
1.231 + asm("cmp r12, #0 ");
1.232 + asm("bne 1b "); // loop until we reach zero terminator
1.233 + asm("sub r3, r3, r1 "); // r3 = 2*length
1.234 + asm("mov r3, r3, lsr #1 "); // r3 = length (+EBufC)
1.235 + asm("cmp r3, r2 "); // check against max length
1.236 + asm("bgt Des16PanicLengthOutOfRange__Fv ");
1.237 + asm("str r3, [r0], #4 "); // save length/type field, r0->buffer
1.238 + asm("add r2, r3, r3 "); // size=2*length into r2 for function call
1.239 + asm("b memmove "); // call memmove
1.240 + }
1.241 +#endif
1.242 +
1.243 +__NAKED__ EXPORT_C void TBufCBase16::Copy(const TDesC16& /*aDes*/,TInt /*aMaxLength*/)
1.244 +//
1.245 +// Copy from a descriptor.
1.246 +//
1.247 + {
1.248 + asm("ldr r3, [r1], #4 "); // r3 = type/length
1.249 + asm("bic r12, r3, #0xF0000000"); // r12 = length
1.250 + asm("cmp r12, r2 "); // compare with maxlength
1.251 + asm("bgt " CSM_Z21Des16PanicDesOverflowv);
1.252 + asm("cmp r3, #0x50000000 ");
1.253 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.254 + asm("eor r3, r3, r3, lsr #1 ");
1.255 + asm("msr cpsr_flg, r3 ");
1.256 + asm("addcs r1, r1, #4 ");
1.257 + asm("ldrle r1, [r1] ");
1.258 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.259 + asm("str r12, [r0], #4 "); // store length/type, r0->buffer
1.260 + asm("add r2, r12, r12 "); // size=2*length into r2 for function call
1.261 + asm("b memmove "); // call memmove
1.262 + }
1.263 +
1.264 +#ifndef __EABI_CTORS__
1.265 +__NAKED__ EXPORT_C TBufBase16::TBufBase16(TInt /*aMaxLength*/)
1.266 + {
1.267 + asm("mov r2, #0x30000000 "); // EBuf + zero length
1.268 + asm("str r2, [r0] ");
1.269 + asm("str r1, [r0, #4] ");
1.270 + __JUMP(,lr);
1.271 + }
1.272 +
1.273 +__NAKED__ EXPORT_C TBufBase16::TBufBase16(TInt /*aLength*/, TInt /*aMaxLength*/)
1.274 + {
1.275 + asm("cmp r1, #0 "); // check length>=0
1.276 + asm("cmpge r2, r1 "); // if so, check maxlength>=length
1.277 + asm("orrge r1, r1, #0x30000000 "); // r1=length + EBuf
1.278 + asm("stmgeia r0, {r1,r2} "); // store length/type and maxlength fields
1.279 + __JUMP(ge,lr);
1.280 + asm("cmp r2, #0 ");
1.281 + asm("bmi " CSM_Z27Des16PanicMaxLengthNegativev);
1.282 + asm("b " CSM_Z26Des16PanicLengthOutOfRangev);
1.283 + }
1.284 +
1.285 +#ifdef __DES16_MACHINE_CODED_HWORD__
1.286 +__NAKED__ EXPORT_C TBufBase16::TBufBase16(const TUint16* /*aString*/, TInt /*aMaxLength*/)
1.287 + {
1.288 + asm("mov r12, r1, lsr #1 "); // save aString pointer (lose bottom bit which should be 0)
1.289 + asm("1: ");
1.290 + asm("ldrh r3, [r1], #2 ");
1.291 + asm("cmp r3, #0 ");
1.292 + asm("bne 1b "); // loop until we reach zero terminator
1.293 + asm("rsb r3, r12, r1, lsr #1 "); // r3 = length + 1
1.294 + asm("sub r3, r3, #1 "); // r3 = length
1.295 + asm("cmp r3, r2 "); // compare to max length
1.296 + asm("bgt Des16PanicLengthOutOfRange__Fv "); // length too big, so panic
1.297 + asm("orr r1, r3, #0x30000000 "); // if length<=max, r1=EBuf + length
1.298 + asm("stmfd sp!, {r0, lr} "); // save registers for function call
1.299 + asm("stmia r0!, {r1, r2} "); // store type/length and max length fields, r0->buffer
1.300 + asm("mov r2, r3, lsl #1 "); // r2=Size()
1.301 + asm("mov r1, r12, lsl #1 "); // r1=aString
1.302 + asm("bl memmove "); // call memmove
1.303 + __POPRET("r0,");
1.304 + }
1.305 +#endif
1.306 +
1.307 +__NAKED__ EXPORT_C TBufBase16::TBufBase16(const TDesC16& /*aDes*/, TInt /*aMaxLength*/)
1.308 + {
1.309 + asm("ldr r3, [r1], #4 "); // r3 = type/length
1.310 + asm("bic r12, r3, #0xF0000000"); // r12 = length
1.311 + asm("cmp r12, r2 "); // compare with maxlength
1.312 + asm("bgt " CSM_Z26Des16PanicLengthOutOfRangev);
1.313 + asm("cmp r3, #0x50000000 ");
1.314 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.315 + asm("eor r3, r3, r3, lsr #1 ");
1.316 + asm("msr cpsr_flg, r3 ");
1.317 + asm("addcs r1, r1, #4 ");
1.318 + asm("ldrle r1, [r1] ");
1.319 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.320 + asm("stmfd sp!, {r0,lr} "); // save registers for function call
1.321 + asm("orr r3, r12, #0x30000000 "); // add EBuf type field
1.322 + asm("str r3, [r0], #4 "); // store length/type, r0->max length
1.323 + asm("str r2, [r0], #4 "); // store max length, r0->buffer
1.324 + asm("mov r2, r12, lsl #1 "); // Size() into r2 for function call
1.325 + asm("bl memmove "); // call memmove
1.326 + __POPRET("r0,");
1.327 + }
1.328 +#endif
1.329 +
1.330 +__NAKED__ EXPORT_C void TDes16::SetLength(TInt /*aLength*/)
1.331 +//
1.332 +// Set the length of the descriptor, checking the length is O.K.
1.333 +//
1.334 + {
1.335 + asm("ldmia r0, {r2,r3} "); // r2=length/type, r3=maxlength
1.336 + asm("cmp r1, r3 "); // check aLength against maxlength and for -ve values
1.337 + asm("bhi " CSM_Z21Des16PanicDesOverflowv);
1.338 + asm("and r2, r2, #0xF0000000 "); // r2=type field
1.339 + asm("cmp r2, #0x40000000 "); // check for EBufCPtr
1.340 + asm("orr r2, r2, r1 "); // r2=type + new length
1.341 + asm("str r2, [r0] "); // store new length
1.342 + __JUMP(ne,lr);
1.343 + asm("ldr r2, [r0, #8] "); // r2=pointer to TBufCBase
1.344 + asm("str r1, [r2] "); // update length of TBufCBase
1.345 + __JUMP(,lr);
1.346 + }
1.347 +
1.348 +__NAKED__ EXPORT_C void TDes16::SetMax()
1.349 +//
1.350 +// Set the length to MaxLength().
1.351 +//
1.352 + {
1.353 + asm("ldmia r0, {r1,r2} "); // r1=length/type, r2=maxlength
1.354 + asm("and r1, r1, #0xF0000000 "); // r1=type field
1.355 + asm("cmp r1, #0x40000000 "); // check for EBufCPtr
1.356 + asm("orr r1, r1, r2 "); // r1=type field + maxlength
1.357 + asm("str r1, [r0] "); // store new length
1.358 + __JUMP(ne,lr);
1.359 + asm("ldr r1, [r0, #8] "); // r1 = pointer to TBufCBase
1.360 + asm("str r2, [r1] "); // update length of TBufCBase
1.361 + __JUMP(,lr);
1.362 + }
1.363 +
1.364 +#ifdef __DES16_MACHINE_CODED_HWORD__
1.365 +__NAKED__ EXPORT_C void TDes16::Copy(const TUint16* /*aString*/)
1.366 +//
1.367 +// Copy a string to this descriptor.
1.368 +//
1.369 + {
1.370 + asm("sub r2, r1, #2 "); // r2=aString-2
1.371 + asm("1: ");
1.372 + asm("ldrh r3, [r2, #2]! ");
1.373 + asm("cmp r3, #0 ");
1.374 + asm("bne 1b "); // loop until zero terminator reached
1.375 + asm("sub r2, r2, r1 "); // r2=2*length of string
1.376 + asm("mov r2, r2, lsr #1 "); // r2=length of string
1.377 + asm("ldmia r0, {r3,r12} "); // r3=type/length of this, r12=maxlength
1.378 + asm("cmp r2, r12 "); // compare new length against maxlength
1.379 + asm("bgt Des16PanicDesOverflow__Fv ");
1.380 + asm("cmp r3, #0x50000000 ");
1.381 + asm("bcs Des16PanicBadDesType__Fv ");
1.382 + asm("and r3, r3, #0xF0000000 "); // r3=type of this
1.383 + asm("orr r3, r3, r2 "); // r3=new type/length
1.384 + asm("str r3, [r0], #4 "); // store it
1.385 + asm("eor r3, r3, r3, lsr #1 ");
1.386 + asm("msr cpsr_flg, r3 ");
1.387 + asm("addcs r0, r0, #4 ");
1.388 + asm("ldrle r0, [r0] ");
1.389 + asm("streq r2, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr()
1.390 + asm("add r2, r2, r2 "); // r2=size=2*length
1.391 + asm("b memmove "); // call memmove
1.392 + }
1.393 +#endif
1.394 +
1.395 +__NAKED__ EXPORT_C void TDes16::Copy(const TUint16* /*aBuf*/,TInt /*aLength*/)
1.396 +//
1.397 +// Copy the aLength characters to the descriptor.
1.398 +//
1.399 + {
1.400 + asm("ldmia r0, {r3,r12} "); // r3=type/length of this, r12=maxlength
1.401 + asm("cmp r2, r12 "); // compare new length against maxlength
1.402 + asm("bhi " CSM_Z21Des16PanicDesOverflowv); // Des16Panic if >MaxLength or -ve
1.403 + asm("cmp r3, #0x50000000 ");
1.404 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.405 + asm("and r3, r3, #0xF0000000 "); // r3=type of this
1.406 + asm("orr r3, r3, r2 "); // r3=new type/length
1.407 + asm("str r3, [r0], #4 "); // store it
1.408 + asm("eor r3, r3, r3, lsr #1 ");
1.409 + asm("msr cpsr_flg, r3 ");
1.410 + asm("addcs r0, r0, #4 ");
1.411 + asm("ldrle r0, [r0] ");
1.412 + asm("streq r2, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr()
1.413 + asm("add r2, r2, r2 "); // r2=size=2*length
1.414 + asm("b memmove "); // call memmove
1.415 + }
1.416 +
1.417 +__NAKED__ EXPORT_C void TDes16::Copy(const TDesC16& /*aDes*/)
1.418 +//
1.419 +// Copy a descriptor to this descriptor.
1.420 +//
1.421 + {
1.422 + asm("ldr r3, [r1], #4 "); // r3 = type/length of aDes
1.423 + asm("bic r12, r3, #0xF0000000"); // r12 = aDes.length
1.424 + asm("ldr r2, [r0, #4] "); // r2=this.maxlength
1.425 + asm("cmp r12, r2 "); // compare with maxlength
1.426 + asm("bgt " CSM_Z21Des16PanicDesOverflowv);
1.427 + asm("ldr r2, [r0] "); // get type of this
1.428 + asm("cmp r2, #0x50000000 "); // check both descriptor types
1.429 + asm("cmpcc r3, #0x50000000 ");
1.430 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.431 + asm("and r2, r2, #0xF0000000 ");
1.432 + asm("orr r2, r12, r2 "); // r2=new type/length of this
1.433 + asm("str r2, [r0], #4 "); // store it
1.434 + asm("eor r3, r3, r3, lsr #1 ");
1.435 + asm("msr cpsr_flg, r3 ");
1.436 + asm("addcs r1, r1, #4 ");
1.437 + asm("ldrle r1, [r1] ");
1.438 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.439 + asm("eor r2, r2, r2, lsr #1 ");
1.440 + asm("msr cpsr_flg, r2 ");
1.441 + asm("addcs r0, r0, #4 ");
1.442 + asm("ldrle r0, [r0] ");
1.443 + asm("streq r12, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr()
1.444 + asm("add r2, r12, r12 "); // size=2*length into r2 for function call
1.445 + asm("b memmove "); // call memmove
1.446 + }
1.447 +
1.448 +__NAKED__ EXPORT_C TPtr16 TDes16::LeftTPtr(TInt /*aLength*/) const
1.449 +//
1.450 +// Extract the left portion of the descriptor.
1.451 +//
1.452 + {
1.453 + // On entry r0=return store ptr, r1=this, r2=aLength
1.454 + // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr)
1.455 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.456 + asm("cmp r2, #0 "); // check aLength>=0
1.457 + asm("blt Des16PanicPosOutOfRange__Fv "); // if not, panic
1.458 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.459 + asm("cmp r2, r12 "); // else limit aLength to Length()
1.460 + asm("movgt r2, r12 ");
1.461 + asm("cmp r3, #0x50000000 ");
1.462 + asm("bcs Des16PanicBadDesType__Fv ");
1.463 + asm("eor r3, r3, r3, lsr #1 ");
1.464 + asm("msr cpsr_flg, r3 ");
1.465 + asm("addcs r1, r1, #4 ");
1.466 + asm("ldrle r1, [r1] ");
1.467 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.468 + asm("mov r3, r1 "); // r3=this.Ptr()
1.469 + asm("orr r1, r2, #0x20000000 "); // r1=aLength + EPtr
1.470 + asm("stmia r0, {r1-r3} ");
1.471 + __JUMP(,lr);
1.472 + }
1.473 +
1.474 +__NAKED__ EXPORT_C TPtr16 TDes16::RightTPtr(TInt /*aLength*/) const
1.475 +//
1.476 +// Extract the right portion of the descriptor.
1.477 +//
1.478 + {
1.479 + // On entry r0=return store ptr, r1=this, r2=aLength
1.480 + // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr)
1.481 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.482 + asm("cmp r2, #0 "); // check aLength>=0
1.483 + asm("blt Des16PanicPosOutOfRange__Fv "); // if not, panic
1.484 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.485 + asm("cmp r2, r12 "); // else limit aLength to Length()
1.486 + asm("movgt r2, r12 ");
1.487 + asm("cmp r3, #0x50000000 ");
1.488 + asm("bcs Des16PanicBadDesType__Fv ");
1.489 + asm("eor r3, r3, r3, lsr #1 ");
1.490 + asm("msr cpsr_flg, r3 ");
1.491 + asm("addcs r1, r1, #4 ");
1.492 + asm("ldrle r1, [r1] ");
1.493 + asm("addeq r1, r1, #4 "); // r0=this.Ptr()
1.494 + asm("add r3, r1, r12, lsl #1 "); // r3=this.Ptr()+len*2
1.495 + asm("orr r1, r2, #0x20000000 "); // r1=aLength + EPtr
1.496 + asm("sub r3, r3, r2, lsl #1 "); // r2=Ptr()+len*2-aLength*2
1.497 + asm("stmia r0, {r1-r3} ");
1.498 + __JUMP(,lr);
1.499 + }
1.500 +
1.501 +__NAKED__ EXPORT_C TPtr16 TDes16::MidTPtr(TInt /*aPos*/) const
1.502 +//
1.503 +// Extract the middle portion of the descriptor.
1.504 +//
1.505 + {
1.506 + // On entry r0=return store ptr, r1=this, r2=aPos
1.507 + // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr)
1.508 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.509 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.510 + asm("cmp r2, #0 "); // check aPos>=0
1.511 + asm("cmpge r12, r2 "); // if so check Length()>=aPos
1.512 + asm("blt Des16PanicPosOutOfRange__Fv ");
1.513 + asm("cmp r3, #0x50000000 ");
1.514 + asm("bcs Des16PanicBadDesType__Fv ");
1.515 + asm("eor r3, r3, r3, lsr #1 ");
1.516 + asm("msr cpsr_flg, r3 ");
1.517 + asm("addcs r1, r1, #4 ");
1.518 + asm("ldrle r1, [r1] ");
1.519 + asm("addeq r1, r1, #4 "); // r0=this.Ptr()
1.520 + asm("add r3, r1, r2, lsl #1 "); // r3=this.Ptr()+aPos*2
1.521 + asm("sub r2, r12, r2 "); // r2=len-aPos (=newMaxLen)
1.522 + asm("orr r1, r2, #0x20000000 "); // r1=len-aPos + EPtr (=newLen/Type)
1.523 + asm("stmia r0, {r1-r3} ");
1.524 + __JUMP(,lr);
1.525 + }
1.526 +
1.527 +__NAKED__ EXPORT_C TPtr16 TDes16::MidTPtr(TInt /*aPos*/,TInt /*aLength*/) const
1.528 +//
1.529 +// Extract the middle portion of the descriptor.
1.530 +//
1.531 + {
1.532 + // On entry r0=return store ptr, r1=this, r2=aPos, r3=aLength
1.533 + // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr)
1.534 + asm("str r4, [sp, #-4]! "); // save r4
1.535 + asm("ldr r12, [r1], #4 "); // r12=this.length/type
1.536 + asm("mov r4, r1 ");
1.537 + asm("cmp r12, #0x50000000 "); // check valid descriptor type
1.538 + asm("bcs Des16PanicBadDesType__Fv ");
1.539 + asm("eor r12, r12, r12, lsr #1 ");
1.540 + asm("msr cpsr_flg, r12 ");
1.541 + asm("ldr r12, [r1, #-4] ");
1.542 + asm("addcs r4, r4, #4 ");
1.543 + asm("ldrle r4, [r4] ");
1.544 + asm("bic r12, r12, #0xF0000000 "); // r12=Length()
1.545 + asm("addeq r4, r4, #4 "); // r4=this.Ptr()
1.546 + asm("cmp r2, #0 "); // check aPos>=0
1.547 + asm("subge r12, r12, r2 "); // if so, r12=Length()-aPos
1.548 + asm("cmpge r12, r3 "); // and check Length()-aPos>=aLength
1.549 + asm("orrge r1, r3, #0x20000000 "); // if so, r0 = aLength + EPtr
1.550 + asm("addge r3, r4, r2, lsl #1 "); // and r2=this.Ptr()+aPos*2
1.551 + asm("bicge r2, r1, #0xF0000000 "); // and r1=aLength
1.552 + asm("stmgeia r0, {r1-r3} ");
1.553 + asm("ldrge r4, [sp], #4 ");
1.554 + __JUMP(ge,lr);
1.555 + asm("b Des16PanicPosOutOfRange__Fv ");
1.556 + }
1.557 +
1.558 +__NAKED__ EXPORT_C const TUint16& TDesC16::AtC(TInt /*anIndex*/) const
1.559 +//
1.560 +// Return a reference to the character in the buffer.
1.561 +//
1.562 + {
1.563 + asm("ldr r2, [r0], #4 "); // r2=length/type
1.564 + asm("bic r3, r2, #0xF0000000 "); // r3=length
1.565 + asm("cmp r2, #0x50000000 ");
1.566 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.567 + asm("eor r2, r2, r2, lsr #1 ");
1.568 + asm("msr cpsr_flg, r2 ");
1.569 + asm("addcs r0, r0, #4 ");
1.570 + asm("ldrle r0, [r0] ");
1.571 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.572 + asm("cmp r1, #0 "); // check index>=0
1.573 + asm("cmpge r3, r1 "); // if so, check Length()>index
1.574 + asm("addgt r0, r0, r1, lsl #1 "); // return value = this.Ptr()+index*2
1.575 + __JUMP(gt,lr);
1.576 + asm("b " CSM_Z28Des16PanicDesIndexOutOfRangev);
1.577 + }
1.578 +
1.579 +#ifdef __DES16_MACHINE_CODED_HWORD__
1.580 +__NAKED__ EXPORT_C TInt TDesC16::Locate(TChar /*aChar*/) const
1.581 +//
1.582 +// Locate character aChar in the descriptor.
1.583 +//
1.584 + {
1.585 + asm("ldr r2, [r0], #4 "); // r2=length/type
1.586 + asm("cmp r2, #0x50000000 ");
1.587 + asm("bcs Des16PanicBadDesType__Fv ");
1.588 + asm("bics r3, r2, #0xF0000000 "); // r3=length
1.589 + asm("mvneq r0, #0 "); // if length=0, not found
1.590 + __JUMP(eq,lr);
1.591 + asm("eor r2, r2, r2, lsr #1 ");
1.592 + asm("msr cpsr_flg, r2 ");
1.593 + asm("addcs r0, r0, #4 ");
1.594 + asm("ldrle r0, [r0] ");
1.595 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.596 + asm("add r3, r0, r3, lsl #1 "); // r3=ptr+length*2 (end of string pointer)
1.597 + asm("add r12, r0, #2 "); // r12=ptr+2
1.598 + asm("1: ");
1.599 + asm("ldrh r2, [r0], #2 "); // r2=*r0++
1.600 + asm("cmp r1, r2 "); // is r1=match char?
1.601 + asm("cmpne r0, r3 "); // if not, is r0=r3 (end pointer)
1.602 + asm("bne 1b ");
1.603 + asm("cmp r1, r2 "); // did we find char?
1.604 + asm("subeq r0, r0, r12 "); // if we did, return value = r0-ptr-2
1.605 + asm("moveq r0, r0, lsr #1 "); // divide by 2 to get index
1.606 + asm("mvnne r0, #0 "); // else return value =-1
1.607 + __JUMP(,lr);
1.608 + }
1.609 +
1.610 +__NAKED__ EXPORT_C TInt TDesC16::LocateReverse(TChar /*aChar*/) const
1.611 +//
1.612 +// Locate character aChar in the descriptor in reverse.
1.613 +//
1.614 + {
1.615 + asm("ldr r2, [r0], #4 "); // r2=length/type
1.616 + asm("cmp r2, #0x50000000 ");
1.617 + asm("bcs Des16PanicBadDesType__Fv ");
1.618 + asm("bics r3, r2, #0xF0000000 "); // r3=length
1.619 + asm("mvneq r0, #0 "); // if length=0, not found
1.620 + __JUMP(eq,lr);
1.621 + asm("eor r2, r2, r2, lsr #1 ");
1.622 + asm("msr cpsr_flg, r2 ");
1.623 + asm("addcs r0, r0, #4 ");
1.624 + asm("ldrle r0, [r0] ");
1.625 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.626 + asm("add r3, r0, r3, lsl #1 "); // r3=Ptr()+Length()
1.627 + asm("1: ");
1.628 + asm("ldrh r2, [r3, #-2]! "); // r2=*--r3
1.629 + asm("cmp r1, r2 "); // is r1=match char?
1.630 + asm("cmpne r3, r0 "); // if not, have we reached beginning of string?
1.631 + asm("bne 1b "); // loop if neither
1.632 + asm("cmp r1, r2 "); // did we find match char?
1.633 + asm("subeq r0, r3, r0 "); // if we did, return value = (r3-r0)/2
1.634 + asm("moveq r0, r0, lsr #1 ");
1.635 + asm("mvnne r0, #0 "); // else return value =-1
1.636 + __JUMP(,lr);
1.637 + }
1.638 +#endif
1.639 +
1.640 +#ifndef __KERNEL_MODE__
1.641 +__NAKED__ EXPORT_C TInt TDesC16::CompareF(const TDesC16& /*aDes*/) const
1.642 +//
1.643 +// Compare a descriptor to this descriptor folded.
1.644 +//
1.645 + {
1.646 + asm("ldr r12, 1f ");
1.647 + asm("b comparebody ");
1.648 + asm("1: ");
1.649 + asm(".word " CSM_ZN3Mem8CompareFEPKtiS0_i);
1.650 + }
1.651 +
1.652 +__NAKED__ EXPORT_C TInt TDesC16::CompareC(const TDesC16& /*aDes*/) const
1.653 +//
1.654 +// Compare a descriptor to this descriptor collated.
1.655 +//
1.656 + {
1.657 + asm("ldr r12, 1f ");
1.658 + asm("b comparebody ");
1.659 + asm("1: ");
1.660 + asm(".word " CSM_ZN3Mem8CompareCEPKtiS0_i);
1.661 + }
1.662 +#endif
1.663 +
1.664 +__NAKED__ EXPORT_C TInt TDesC16::Compare(const TDesC16& /*aDes*/) const
1.665 +//
1.666 +// Compare a descriptor to this descriptor.
1.667 +//
1.668 + {
1.669 + asm("ldr r12, 1f ");
1.670 + asm("comparebody: ");
1.671 + asm("mov r2, r1 "); // r2=&aDes
1.672 + asm("ldr r3, [r0], #4 "); // r3=this.length/type
1.673 + asm("cmp r3, #0x50000000 ");
1.674 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.675 + asm("bic r1, r3, #0xF0000000 "); // r1=this.Length()
1.676 + asm("eor r3, r3, r3, lsr #1 ");
1.677 + asm("msr cpsr_flg, r3 ");
1.678 + asm("addcs r0, r0, #4 ");
1.679 + asm("ldrle r0, [r0] ");
1.680 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.681 + asm("ldr r3, [r2], #4 "); // r3=aDes.length/type
1.682 + asm("cmp r3, #0x50000000 ");
1.683 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.684 + asm("eor r3, r3, r3, lsr #1 ");
1.685 + asm("msr cpsr_flg, r3 ");
1.686 + asm("ldr r3, [r2, #-4] ");
1.687 + asm("bic r3, r3, #0xF0000000 "); // r3=aDes.Length()
1.688 + asm("addcs r2, r2, #4 ");
1.689 + asm("ldrle r2, [r2] ");
1.690 + asm("addeq r2, r2, #4 "); // r2=aDes.Ptr()
1.691 +#ifdef __KERNEL_MODE__
1.692 + asm("add r1, r1, r1 ");
1.693 + asm("add r3, r3, r3 ");
1.694 +#endif
1.695 + __JUMP(,r12);
1.696 +
1.697 + asm("1: ");
1.698 +#ifdef __KERNEL_MODE__
1.699 + asm(".word memcompare ");
1.700 +#else
1.701 + asm(".word " CSM_ZN3Mem7CompareEPKtiS0_i);
1.702 +#endif
1.703 + }
1.704 +#endif // __DES16_MACHINE_CODED__
1.705 +
1.706 +
1.707 +#if defined(__DES16_MACHINE_CODED__) && !defined(__EABI__)
1.708 +__NAKED__ EXPORT_C TPtrC16 TDesC16::Left(TInt /*aLength*/) const
1.709 +//
1.710 +// Extract the left portion of the descriptor.
1.711 +//
1.712 + {
1.713 + // On entry r0=this, r1=aLength
1.714 + // Return TPtrC16 in r0,r1
1.715 + asm("ldr r3, [r0], #4 "); // r3=this.length/type
1.716 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.717 + asm("cmp r1, #0 "); // check aLength>=0
1.718 + asm("blt " CSM_Z23Des16PanicPosOutOfRangev); // if not, panic
1.719 + asm("cmp r1, r12 "); // else limit aLength to Length()
1.720 + asm("movgt r1, r12 ");
1.721 + asm("cmp r3, #0x50000000 ");
1.722 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.723 + asm("eor r3, r3, r3, lsr #1 ");
1.724 + asm("msr cpsr_flg, r3 ");
1.725 + asm("addcs r0, r0, #4 ");
1.726 + asm("ldrle r0, [r0] ");
1.727 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.728 + asm("orr r2, r1, #0x10000000 "); // r2=aLength + EPtrC
1.729 + asm("mov r1, r0 "); // r1=result ptr
1.730 + asm("mov r0, r2 "); // r0=result type/length
1.731 + __JUMP(,lr);
1.732 + }
1.733 +
1.734 +__NAKED__ EXPORT_C TPtrC16 TDesC16::Right(TInt /*aLength*/) const
1.735 +//
1.736 +// Extract the right portion of the descriptor.
1.737 +//
1.738 + {
1.739 + // On entry r0=this, r1=aLength
1.740 + // Return TPtrC16 in r0,r1
1.741 + asm("ldr r3, [r0], #4 "); // r3=this.length/type
1.742 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.743 + asm("cmp r1, #0 "); // check aLength>=0
1.744 + asm("blt " CSM_Z23Des16PanicPosOutOfRangev); // if not, panic
1.745 + asm("cmp r1, r12 "); // else limit aLength to Length()
1.746 + asm("movgt r1, r12 ");
1.747 + asm("cmp r3, #0x50000000 ");
1.748 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.749 + asm("eor r3, r3, r3, lsr #1 ");
1.750 + asm("msr cpsr_flg, r3 ");
1.751 + asm("addcs r0, r0, #4 ");
1.752 + asm("ldrle r0, [r0] ");
1.753 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.754 + asm("add r3, r0, r12, lsl #1 "); // r3=this.Ptr()+len*2
1.755 + asm("orr r0, r1, #0x10000000 "); // r0=aLength + EPtrC
1.756 + asm("sub r1, r3, r1, lsl #1 "); // r1=Ptr()+len*2-aLength*2
1.757 + __JUMP(,lr);
1.758 + }
1.759 +
1.760 +__NAKED__ EXPORT_C TPtrC16 TDesC16::Mid(TInt /*aPos*/) const
1.761 +//
1.762 +// Extract the middle portion of the descriptor.
1.763 +//
1.764 + {
1.765 + // On entry r0=this, r1=aPos
1.766 + // Return TPtrC16 in r0,r1
1.767 + asm("ldr r3, [r0], #4 "); // r3=this.length/type
1.768 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.769 + asm("cmp r1, #0 "); // check aPos>=0
1.770 + asm("cmpge r12, r1 "); // if so check Length()>=aPos
1.771 + asm("blt " CSM_Z23Des16PanicPosOutOfRangev);
1.772 + asm("cmp r3, #0x50000000 ");
1.773 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.774 + asm("eor r3, r3, r3, lsr #1 ");
1.775 + asm("msr cpsr_flg, r3 ");
1.776 + asm("addcs r0, r0, #4 ");
1.777 + asm("ldrle r0, [r0] ");
1.778 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.779 + asm("sub r2, r12, r1 "); // r2=len-aPos
1.780 + asm("add r1, r0, r1, lsl #1 "); // r1=this.Ptr()+aPos*2
1.781 + asm("orr r0, r2, #0x10000000 "); // r0=result length + EPtrC
1.782 + __JUMP(,lr);
1.783 + }
1.784 +
1.785 +__NAKED__ EXPORT_C TPtrC16 TDesC16::Mid(TInt /*aPos*/,TInt /*aLength*/) const
1.786 +//
1.787 +// Extract the middle portion of the descriptor.
1.788 +//
1.789 + {
1.790 + // On entry r0=this, r1=aPos, r2=aLength
1.791 + // Return TPtrC16 in r0,r1
1.792 + asm("ldr r12, [r0], #4 "); // r12=this.length/type
1.793 + asm("cmp r12, #0x50000000 "); // check valid descriptor type
1.794 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.795 + asm("eor r12, r12, r12, lsr #1 ");
1.796 + asm("msr cpsr_flg, r12 ");
1.797 + asm("ldr r12, [r0, #-4] ");
1.798 + asm("bic r12, r12, #0xF0000000 "); // r12=Length()
1.799 + asm("addcs r0, r0, #4 ");
1.800 + asm("ldrle r0, [r0] ");
1.801 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.802 + asm("cmp r1, #0 "); // check aPos>=0
1.803 + asm("subge r12, r12, r1 "); // if so, r12=Length()-aPos
1.804 + asm("cmpge r12, r2 "); // and check Length()-aPos>=aLength
1.805 + asm("addge r1, r0, r1, lsl #1 "); // if so, r1=Ptr()+aPos*2
1.806 + asm("orrge r0, r2, #0x10000000 "); // and r0 = aLength + EPtrC
1.807 + __JUMP(ge,lr);
1.808 + asm("b " CSM_Z23Des16PanicPosOutOfRangev);
1.809 + }
1.810 +#endif // defined(__DES16_MACHINE_CODED__) && !defined(__EABI__)
1.811 +
1.812 +
1.813 +#ifdef __DES16_MACHINE_CODED__
1.814 +
1.815 +// Here are the __EABI__ compliant versions of the above
1.816 +#ifdef __EABI__
1.817 +__NAKED__ EXPORT_C TPtrC16 TDesC16::Left(TInt /*aLength*/) const
1.818 +//
1.819 +// Extract the left portion of the descriptor.
1.820 +//
1.821 + {
1.822 + // On entry r0=return store ptr, r1=this, r2=aLength
1.823 + // Return TPtr16 ([r0]=length/type,[r0,#4]=Ptr)
1.824 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.825 + asm("cmp r2, #0 "); // check aLength>=0
1.826 + asm("blt Des16PanicPosOutOfRange__Fv "); // if not, panic
1.827 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.828 + asm("cmp r2, r12 "); // else limit aLength to Length()
1.829 + asm("movgt r2, r12 ");
1.830 + asm("cmp r3, #0x50000000 ");
1.831 + asm("bcs Des16PanicBadDesType__Fv ");
1.832 + asm("eor r3, r3, r3, lsr #1 ");
1.833 + asm("msr cpsr_flg, r3 ");
1.834 + asm("addcs r1, r1, #4 ");
1.835 + asm("ldrle r1, [r1] ");
1.836 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.837 + asm("mov r3, r1"); // r3=this.Ptr()
1.838 + asm("orr r1, r2, #0x10000000 "); // r1=aLength + EPtrC
1.839 + asm("stmia r0, {r1,r3} ");
1.840 + __JUMP(,lr);
1.841 + }
1.842 +
1.843 +__NAKED__ EXPORT_C TPtrC16 TDesC16::Right(TInt /*aLength*/) const
1.844 +//
1.845 +// Extract the right portion of the descriptor.
1.846 +//
1.847 + {
1.848 + // On entry r0=return store ptr, r1=this, r2=aLength
1.849 + // Return TPtr16 ([r0]=length/type,[r0,#4]=Ptr)
1.850 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.851 + asm("cmp r2, #0 "); // check aLength>=0
1.852 + asm("blt Des16PanicPosOutOfRange__Fv "); // if not, panic
1.853 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.854 + asm("cmp r2, r12 "); // else limit aLength to Length()
1.855 + asm("movgt r2, r12 ");
1.856 + asm("cmp r3, #0x50000000 ");
1.857 + asm("bcs Des16PanicBadDesType__Fv ");
1.858 + asm("eor r3, r3, r3, lsr #1 ");
1.859 + asm("msr cpsr_flg, r3 ");
1.860 + asm("addcs r1, r1, #4 ");
1.861 + asm("ldrle r1, [r1] ");
1.862 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.863 + asm("add r3, r1, r12, lsl #1 "); // r3=this.Ptr()+len*2
1.864 + asm("orr r1, r2, #0x10000000 "); // r1=aLength + EPtrC
1.865 + asm("sub r3, r3, r2, lsl #1 "); // r2=Ptr()+len*2-aLength*2
1.866 + asm("stmia r0, {r1,r3} ");
1.867 + __JUMP(,lr);
1.868 + }
1.869 +
1.870 +__NAKED__ EXPORT_C TPtrC16 TDesC16::Mid(TInt /*aPos*/) const
1.871 +//
1.872 +// Extract the middle portion of the descriptor.
1.873 +//
1.874 + {
1.875 + // On entry r0=return store ptr, r1=this, r2=aPos
1.876 + // Return TPtr16 ([r0]=length/type,[r0,#4]=Ptr)
1.877 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.878 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.879 + asm("cmp r2, #0 "); // check aPos>=0
1.880 + asm("cmpge r12, r2 "); // if so check Length()>=aPos
1.881 + asm("blt Des16PanicPosOutOfRange__Fv ");
1.882 + asm("cmp r3, #0x50000000 ");
1.883 + asm("bcs Des16PanicBadDesType__Fv ");
1.884 + asm("eor r3, r3, r3, lsr #1 ");
1.885 + asm("msr cpsr_flg, r3 ");
1.886 + asm("addcs r1, r1, #4 ");
1.887 + asm("ldrle r1, [r1] ");
1.888 + asm("addeq r1, r1, #4 "); // r3=this.Ptr()
1.889 + asm("add r3, r1, r2, lsl #1 "); // r3=this.Ptr()+aPos*2
1.890 + asm("sub r2, r12, r2 "); // r2=len-aPos (=newMaxLen)
1.891 + asm("orr r1, r2, #0x10000000 "); // r1=len-aPos + EPtrC (=newLen/Type)
1.892 + asm("stmia r0, {r1,r3} ");
1.893 + __JUMP(,lr);
1.894 + }
1.895 +
1.896 +__NAKED__ EXPORT_C TPtrC16 TDesC16::Mid(TInt /*aPos*/,TInt /*aLength*/) const
1.897 +//
1.898 +// Extract the middle portion of the descriptor.
1.899 +//
1.900 + {
1.901 + // On entry r0=return store ptr, r1=this, r2=aPos, r3=aLength
1.902 + // Return TPtr16 ([r0]=length/type,[r0,#4]=Ptr)
1.903 + asm("ldr r12, [r1], #4 "); // r12=this.length/type
1.904 + asm("cmp r12, #0x50000000 "); // check valid descriptor type
1.905 + asm("bcs Des16PanicBadDesType__Fv ");
1.906 + asm("eor r12, r12, r12, lsr #1 ");
1.907 + asm("msr cpsr_flg, r12 ");
1.908 + asm("ldr r12, [r1, #-4] ");
1.909 + asm("addcs r1, r1, #4 ");
1.910 + asm("ldrle r1, [r1] ");
1.911 + asm("bic r12, r12, #0xF0000000 "); // r12=Length()
1.912 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.913 + asm("cmp r2, #0 "); // check aPos>=0
1.914 + asm("subge r12, r12, r2 "); // if so, r12=Length()-aPos
1.915 + asm("cmpge r12, r3 "); // and check Length()-aPos>=aLength
1.916 + asm("addge r2, r1, r2, lsl #1 "); // if so r2=this.Ptr()+aPos*2
1.917 + asm("orrge r1, r3, #0x10000000 "); // and r1 = aLength + EPtrC
1.918 + asm("stmgeia r0, {r1,r2} ");
1.919 + __JUMP(ge,lr);
1.920 + asm("b Des16PanicPosOutOfRange__Fv ");
1.921 + }
1.922 +#endif // __EABI__
1.923 +
1.924 +
1.925 +__NAKED__ EXPORT_C void TDes16::Zero()
1.926 +//
1.927 +// Zero the buffer.
1.928 +//
1.929 + {
1.930 + asm("ldr r1, [r0] "); // r1=length/type
1.931 + asm("and r1, r1, #0xF0000000 "); // r1=type field, zero length
1.932 + asm("cmp r1, #0x40000000 "); // check for EBufCPtr
1.933 + asm("str r1, [r0] "); // store zero length
1.934 + __JUMP(ne,lr);
1.935 + asm("ldr r2, [r0, #8] "); // r2 = pointer to TBufCBase
1.936 + asm("mov r1, #0 ");
1.937 + asm("str r1, [r2] "); // update length of TBufCBase
1.938 + __JUMP(,lr);
1.939 + }
1.940 +
1.941 +#ifdef __DES16_MACHINE_CODED_HWORD__
1.942 +#ifndef __KERNEL_MODE__
1.943 +__NAKED__ EXPORT_C void TDes16::ZeroTerminate()
1.944 +//
1.945 +// Zero terminate at Length().
1.946 +//
1.947 + {
1.948 + // Fall though to PtrZ below...
1.949 + }
1.950 +
1.951 +__NAKED__ EXPORT_C const TUint16* TDes16::PtrZ()
1.952 +//
1.953 +// Return a pointer to a 0 terminated string.
1.954 +//
1.955 + {
1.956 + asm("ldmia r0, {r1,r2} "); // r1=length/type, r2=maxlength
1.957 + asm("bic r3, r1, #0xF0000000 "); // r3=Length();
1.958 + asm("cmp r3, r2 "); // check Length()<MaxLength()
1.959 + asm("bge Des16PanicDesOverflow__Fv ");
1.960 + asm("cmp r1, #0x50000000 ");
1.961 + asm("bcs Des16PanicBadDesType__Fv ");
1.962 + asm("eor r1, r1, r1, lsr #1 ");
1.963 + asm("msr cpsr_flg, r1 ");
1.964 + asm("add r0, r0, #4 ");
1.965 + asm("addcs r0, r0, #4 ");
1.966 + asm("ldrle r0, [r0] ");
1.967 + asm("addeq r0, r0, #4 "); // r0=Ptr()
1.968 + asm("add r1, r0, r3, lsl #1 "); // r1=Ptr()+Length()
1.969 + asm("mov r2, #0 ");
1.970 + asm("strh r2, [r1] "); // Ptr()[Length()]=0;
1.971 + __JUMP(,lr);
1.972 + }
1.973 +#endif // __KERNEL_MODE__
1.974 +
1.975 +__NAKED__ EXPORT_C void TDes16::Append(TChar /*aChar*/)
1.976 +//
1.977 +// Add a character at the end of the string.
1.978 +//
1.979 + {
1.980 + asm("ldmia r0, {r2,r3} "); // r2=length/type, r3=maxlength
1.981 + asm("bic r12, r2, #0xF0000000 "); // r12=Length();
1.982 + asm("cmp r12, r3 "); // check Length()<MaxLength()
1.983 + asm("bge Des16PanicDesOverflow__Fv ");
1.984 + asm("cmp r2, #0x50000000 ");
1.985 + asm("bcs Des16PanicBadDesType__Fv ");
1.986 + asm("add r2, r2, #1 "); // increment length by 1
1.987 + asm("str r2, [r0] "); // store new length
1.988 + asm("eor r2, r2, r2, lsr #1 ");
1.989 + asm("msr cpsr_flg, r2 ");
1.990 + asm("add r2, r0, #4 "); // r2=this+4
1.991 + asm("addcs r2, r2, #4 ");
1.992 + asm("ldrle r2, [r2] ");
1.993 + asm("addeq r3, r12, #1 "); // if EBufCPtr, r3=Length()+1
1.994 + asm("streq r3, [r2], #4 "); // and update length of TBufCBase, r2=Ptr()
1.995 + asm("add r2, r2, r12, lsl #1 "); // r2=Ptr()+Length()
1.996 + asm("strh r1, [r2] "); // Ptr()[Length()]=aChar;
1.997 + __JUMP(,lr);
1.998 + }
1.999 +#endif
1.1000 +
1.1001 +__NAKED__ EXPORT_C void TDes16::Append(const TDesC16& /*aDes*/)
1.1002 +//
1.1003 +// Append a descriptor to this descriptor.
1.1004 +//
1.1005 + {
1.1006 + asm("ldr r3, [r1], #4 "); // r3=aDes.length/type
1.1007 + asm("cmp r3, #0x50000000 ");
1.1008 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.1009 + asm("bics r2, r3, #0xF0000000 "); // r2=aDes.Length()
1.1010 + __JUMP(eq,lr);
1.1011 + asm("eor r3, r3, r3, lsr #1 ");
1.1012 + asm("msr cpsr_flg, r3 ");
1.1013 + asm("addcs r1, r1, #4 ");
1.1014 + asm("ldrle r1, [r1] ");
1.1015 + asm("addeq r1, r1, #4 "); // r1=aDes.Ptr()
1.1016 + asm("b appendbody "); // use following routine for rest of job
1.1017 + }
1.1018 +
1.1019 +__NAKED__ EXPORT_C void TDes16::Append(const TUint16* /*aBuf*/,TInt /*aLength*/)
1.1020 +//
1.1021 +// Append aLength from aBuf characters to the descriptor.
1.1022 +//
1.1023 + {
1.1024 + asm("cmp r2, #0 "); // check aLength>=0
1.1025 + __JUMP(eq,lr);
1.1026 + asm("blt " CSM_Z24Des16PanicLengthNegativev);
1.1027 + asm("appendbody: ");
1.1028 + asm("ldmia r0, {r3,r12} "); // r3=type/length, r12=maxlength
1.1029 + asm("cmp r3, #0x50000000 ");
1.1030 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.1031 + asm("bic r3, r3, #0xF0000000 "); // r3=Length()
1.1032 + asm("sub r12, r12, r3 "); // r12=MaxLength-Length
1.1033 + asm("cmp r2, r12 "); // check aLength<=(MaxLength-Length)
1.1034 + asm("bgt " CSM_Z21Des16PanicDesOverflowv);
1.1035 + asm("ldr r12, [r0] ");
1.1036 + asm("add r12, r12, r2 "); // new length/type field
1.1037 + asm("str r12, [r0], #4 "); // store it
1.1038 + asm("eor r12, r12, r12, lsr #1 ");
1.1039 + asm("msr cpsr_flg, r12 ");
1.1040 + asm("addcs r0, r0, #4 ");
1.1041 + asm("ldrle r0, [r0] ");
1.1042 + asm("ldreq r12, [r0] "); // fetch length from TBufCBase
1.1043 + asm("addeq r12, r12, r2 "); // add aLength
1.1044 + asm("streq r12, [r0], #4 "); // update length of TBufCBase, r0=Ptr()
1.1045 + asm("add r0, r0, r3, lsl #1 "); // r0=Ptr()+Length()*2
1.1046 + asm("add r2, r2, r2 "); // r2=aLength*2
1.1047 + asm("b memmove "); // call memmove
1.1048 + }
1.1049 +
1.1050 +__NAKED__ EXPORT_C void TDes16::FillZ()
1.1051 +//
1.1052 +// Fill the descriptor with 0.
1.1053 +//
1.1054 + {
1.1055 + asm("ldr r2, [r0] "); // r2=length/type
1.1056 + asm("cmp r2, #0x50000000 ");
1.1057 + asm("bcs " CSM_Z20Des16PanicBadDesTypev);
1.1058 + asm("bic r1, r2, #0xF0000000 "); // r1=Length()
1.1059 + asm("eor r2, r2, r2, lsr #1 ");
1.1060 + asm("msr cpsr_flg, r2 ");
1.1061 + asm("add r0, r0, #4 ");
1.1062 + asm("addcs r0, r0, #4 ");
1.1063 + asm("ldrle r0, [r0] ");
1.1064 + asm("addeq r0, r0, #4 "); // r0=Ptr()
1.1065 + asm("add r1, r1, r1 "); // r1=2*Length()
1.1066 + asm("b memclr "); // call memclr
1.1067 + }
1.1068 +
1.1069 +#ifdef __DES16_MACHINE_CODED_HWORD__
1.1070 +__NAKED__ EXPORT_C void TDes16::Fill(TChar /*aChar*/)
1.1071 +//
1.1072 +// Fill the descriptor with aChar.
1.1073 +//
1.1074 + {
1.1075 + // on entry r0=this, r1=fill char
1.1076 + asm("ldr r3, [r0] "); // r3=length/type
1.1077 + asm("cmp r3, #0x50000000 ");
1.1078 + asm("bcs Des16PanicBadDesType__Fv ");
1.1079 + asm("bics r2, r3, #0xF0000000 "); // r2=Length()
1.1080 + __JUMP(eq,lr); // if length is zero, finished
1.1081 + asm("stmfd sp!, {r0,lr} "); // save registers for function call
1.1082 + asm("eor r3, r3, r3, lsr #1 ");
1.1083 + asm("msr cpsr_flg, r3 ");
1.1084 + asm("add r0, r0, #4 ");
1.1085 + asm("addcs r0, r0, #4 ");
1.1086 + asm("ldrle r0, [r0] ");
1.1087 + asm("addeq r0, r0, #4 "); // r0=Ptr()
1.1088 + asm("tst r0, #2 "); // check alignment of Ptr()
1.1089 + asm("strneh r1, [r0], #2 "); // if not aligned, fill first location
1.1090 + asm("subne r2, r2, #1 "); // and decrement length
1.1091 + asm("mov r1, r1, lsl #16 ");
1.1092 + asm("orr r1, r1, r1, lsr #16 "); // r1=fill char repeated
1.1093 + asm("mov r3, r1 ");
1.1094 + asm("mov r12, r1 ");
1.1095 + asm("mov r14, r1 "); // r1=r3=r12=r14=fill char repeated
1.1096 + asm("b 2f "); // branch to check for 16-char blocks
1.1097 + asm("1: ");
1.1098 + asm("stmia r0!, {r1,r3,r12,r14} "); // fill a block of 16 bytes
1.1099 + asm("stmia r0!, {r1,r3,r12,r14} "); // fill a block of 16 bytes
1.1100 + asm("2: ");
1.1101 + asm("subs r2, r2, #16 "); // check for more blocks of 16
1.1102 + asm("bge 1b "); // loop if more
1.1103 + asm("add r2, r2, #16 "); // now r1=number of chars remaining, 0<=r1<16
1.1104 + asm("mov r2, r2, lsl #28 "); // move into bits 28-31
1.1105 + asm("msr cpsr_flg, r2 "); // and into NZCV flags
1.1106 + asm("stmmiia r0!, {r1,r3,r12,r14} "); // fill a block of 16 bytes if needed
1.1107 + asm("stmeqia r0!, {r1,r3} "); // fill a block of 8 bytes if needed
1.1108 + asm("stmcsia r0!, {r1} "); // fill a block of 4 bytes if needed
1.1109 + asm("strvsh r1, [r0], #2 "); // fill last char if needed
1.1110 + __POPRET("r0,");
1.1111 + }
1.1112 +#endif
1.1113 +
1.1114 +#endif // __DES16_MACHINE_CODED__
1.1115 +
1.1116 +
1.1117 +
1.1118 +