1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/common/arm/cdes8.cia Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1510 @@
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\cdes8.cia
1.18 +//
1.19 +//
1.20 +
1.21 +#include <e32cia.h>
1.22 +#include "../common.h"
1.23 +
1.24 +#define __FIXED_POINT_64BIT_DIV10__
1.25 +
1.26 +#if defined(__DES8_MACHINE_CODED__) || defined(__EABI__)
1.27 +
1.28 +GLREF_C void Des8PanicBadDesType();
1.29 +GLREF_C void Des8PanicPosOutOfRange();
1.30 +
1.31 +#endif
1.32 +
1.33 +#ifdef __DES8_MACHINE_CODED__
1.34 +
1.35 +GLREF_C void Des8PanicLengthNegative();
1.36 +GLREF_C void Des8PanicMaxLengthNegative();
1.37 +GLREF_C void Des8PanicLengthOutOfRange();
1.38 +GLREF_C void Des8PanicDesOverflow();
1.39 +GLREF_C void Des8PanicDesIndexOutOfRange();
1.40 +
1.41 +__NAKED__ EXPORT_C const TUint8 *TDesC8::Ptr() const
1.42 +//
1.43 +// Return a pointer to the buffer.
1.44 +//
1.45 + {
1.46 + asm("ldr r1, [r0], #4 ");
1.47 + asm("cmp r1, #0x50000000 ");
1.48 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.49 + asm("eor r1, r1, r1, lsr #1 ");
1.50 + asm("msr cpsr_flg, r1 ");
1.51 + asm("addcs r0, r0, #4 ");
1.52 + asm("ldrle r0, [r0] ");
1.53 + asm("addeq r0, r0, #4 ");
1.54 + __JUMP(,lr);
1.55 + }
1.56 +
1.57 +#ifndef __EABI_CTORS__
1.58 +__NAKED__ EXPORT_C TPtrC8::TPtrC8()
1.59 +//
1.60 +// Default constructor
1.61 +//
1.62 + {
1.63 + asm("mov r1, #0x10000000 "); // type=EPtrC, length=0
1.64 + asm("mov r2, #0 "); // ptr=NULL
1.65 + asm("stmia r0, {r1,r2} ");
1.66 + __JUMP(,lr);
1.67 + }
1.68 +
1.69 +__NAKED__ EXPORT_C TPtrC8::TPtrC8(const TDesC8& /*aDes*/)
1.70 +//
1.71 +// Constructor
1.72 +//
1.73 + {
1.74 + asm("ldr r2, [r1], #4 "); // r2 = type/length
1.75 + asm("bic r3, r2, #0xF0000000"); // r3 = length
1.76 + asm("orr r3, r3, #0x10000000"); // r3 = EPtrC + length
1.77 + asm("cmp r2, #0x50000000 ");
1.78 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.79 + asm("eor r2, r2, r2, lsr #1 ");
1.80 + asm("msr cpsr_flg, r2 ");
1.81 + asm("addcs r1, r1, #4 ");
1.82 + asm("ldrle r1, [r1] ");
1.83 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.84 + asm("str r3, [r0] ");
1.85 + asm("str r1, [r0, #4] ");
1.86 + __JUMP(,lr);
1.87 + }
1.88 +
1.89 +__NAKED__ EXPORT_C TPtrC8::TPtrC8(const TUint8* /*aString*/)
1.90 +//
1.91 +// Constructor
1.92 +//
1.93 + {
1.94 + asm("mov r2, r1 "); // save aString pointer
1.95 + asm("1: ");
1.96 + asm("ldrb r3, [r1], #1 ");
1.97 + asm("cmp r3, #0 ");
1.98 + asm("bne 1b "); // loop until we reach zero terminator
1.99 + asm("sub r1, r1, r2 "); // r1 = length + 1
1.100 + asm("sub r1, r1, #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 +
1.106 +__NAKED__ EXPORT_C TPtrC8::TPtrC8(const TUint8* /*aBuf*/,TInt /*aLength*/)
1.107 +//
1.108 +// Constructor
1.109 +//
1.110 + {
1.111 + asm("orrs r2, r2, #0x10000000 ");
1.112 + asm("strpl r2, [r0] ");
1.113 + asm("strpl r1, [r0, #4] ");
1.114 + __JUMP(pl,lr);
1.115 + asm("b " CSM_Z23Des8PanicLengthNegativev);
1.116 + }
1.117 +
1.118 +__NAKED__ EXPORT_C TPtr8::TPtr8(TUint8* /*aBuf*/,TInt /*aMaxLength*/)
1.119 +//
1.120 +// Constructor
1.121 +//
1.122 + {
1.123 + asm("cmp r2, #0 ");
1.124 + asm("movpl r3, r1 ");
1.125 + asm("movpl r1, #0x20000000 "); // length=0, EPtr
1.126 + asm("stmplia r0, {r1,r2,r3} ");
1.127 + __JUMP(pl,lr);
1.128 + asm("b " CSM_Z26Des8PanicMaxLengthNegativev);
1.129 + }
1.130 +
1.131 +__NAKED__ EXPORT_C TPtr8::TPtr8(TUint8* /*aBuf*/,TInt /*aLength*/,TInt /*aMaxLength*/)
1.132 +//
1.133 +// Constructor
1.134 +//
1.135 + {
1.136 + asm("cmp r2, #0 "); // check length>=0
1.137 + asm("cmpge r3, r2 "); // if so, check maxlength>=length
1.138 + asm("movge r12, r1 ");
1.139 + asm("orrge r2, r2, #0x20000000 "); // r2 = length + EPtr
1.140 + asm("stmgeia r0, {r2,r3,r12} ");
1.141 + __JUMP(ge,lr);
1.142 + asm("cmp r2, #0 ");
1.143 + asm("bmi " CSM_Z23Des8PanicLengthNegativev);
1.144 + asm("cmp r3, #0 ");
1.145 + asm("bmi " CSM_Z26Des8PanicMaxLengthNegativev);
1.146 + asm("b " CSM_Z25Des8PanicLengthOutOfRangev);
1.147 + }
1.148 +
1.149 +__NAKED__ EXPORT_C TPtr8::TPtr8(TBufCBase8& /*aLcb*/,TInt /*aMaxLength*/)
1.150 +//
1.151 +// Constructor
1.152 +//
1.153 + {
1.154 + asm("mov r3, r1 ");
1.155 + asm("ldr r1, [r3] ");
1.156 + asm("bic r1, r1, #0xF0000000 "); // r1=aLcb.Length()
1.157 + asm("cmp r1, r2 "); // check against maxlength
1.158 + asm("orrle r1, r1, #0x40000000 "); // r1=aLcb.Length() + EBufCPtr
1.159 + asm("stmleia r0, {r1,r2,r3} ");
1.160 + __JUMP(le,lr);
1.161 + asm("b " CSM_Z25Des8PanicLengthOutOfRangev);
1.162 + }
1.163 +
1.164 +__NAKED__ EXPORT_C TBufCBase8::TBufCBase8()
1.165 +//
1.166 +// Constructor
1.167 +//
1.168 + {
1.169 + asm("mov r1, #0 ");
1.170 + asm("str r1, [r0] ");
1.171 + __JUMP(,lr);
1.172 + }
1.173 +
1.174 +__NAKED__ EXPORT_C TBufCBase8::TBufCBase8(const TUint8* /*aString*/,TInt /*aMaxLength*/)
1.175 +//
1.176 +// Constructor
1.177 +//
1.178 + {
1.179 + asm("mov r3, r1 "); // save aString pointer
1.180 + asm("1: ");
1.181 + asm("ldrb r12, [r3], #1 ");
1.182 + asm("cmp r12, #0 ");
1.183 + asm("bne 1b "); // loop until we reach zero terminator
1.184 + asm("sub r3, r3, r1 "); // r3 = length + 1
1.185 + asm("sub r3, r3, #1 "); // r3 = length (+EBufC)
1.186 + asm("cmp r3, r2 "); // check against max length
1.187 + asm("bgt " CSM_Z25Des8PanicLengthOutOfRangev);
1.188 + asm("stmfd sp!, {r0,lr} "); // save registers for function call
1.189 + asm("str r3, [r0], #4 "); // save length/type field, r0->buffer
1.190 + asm("mov r2, r3 "); // length into r2 for function call
1.191 + asm("bl memmove ");
1.192 + __POPRET("r0,");
1.193 + }
1.194 +
1.195 +__NAKED__ EXPORT_C TBufCBase8::TBufCBase8(const TDesC8& /*aDes*/,TInt /*aMaxLength*/)
1.196 +//
1.197 +// Constructor
1.198 +//
1.199 + {
1.200 + asm("ldr r3, [r1], #4 "); // r3 = type/length
1.201 + asm("bic r12, r3, #0xF0000000"); // r12 = length
1.202 + asm("cmp r12, r2 "); // compare with maxlength
1.203 + asm("bgt " CSM_Z25Des8PanicLengthOutOfRangev);
1.204 + asm("cmp r3, #0x50000000 ");
1.205 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.206 + asm("eor r3, r3, r3, lsr #1 ");
1.207 + asm("msr cpsr_flg, r3 ");
1.208 + asm("addcs r1, r1, #4 ");
1.209 + asm("ldrle r1, [r1] ");
1.210 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.211 + asm("stmfd sp!, {r0,lr} "); // save registers for function call
1.212 + asm("str r12, [r0], #4 "); // store length/type, r0->buffer
1.213 + asm("mov r2, r12 "); // length into r2 for function call
1.214 + asm("bl memmove ");
1.215 + __POPRET("r0,");
1.216 + }
1.217 +#endif
1.218 +
1.219 +__NAKED__ EXPORT_C void TBufCBase8::Copy(const TUint8* /*aString*/,TInt /*aMaxLength*/)
1.220 +//
1.221 +// Copy from a string.
1.222 +//
1.223 + {
1.224 + asm("mov r3, r1 "); // save aString pointer
1.225 + asm("1: ");
1.226 + asm("ldrb r12, [r3], #1 ");
1.227 + asm("cmp r12, #0 ");
1.228 + asm("bne 1b "); // loop until we reach zero terminator
1.229 + asm("sub r3, r3, r1 "); // r3 = length + 1
1.230 + asm("sub r3, r3, #1 "); // r3 = length (+EBufC)
1.231 + asm("cmp r3, r2 "); // check against max length
1.232 + asm("bgt " CSM_Z25Des8PanicLengthOutOfRangev);
1.233 + asm("str r3, [r0], #4 "); // save length/type field, r0->buffer
1.234 + asm("mov r2, r3 "); // length into r2 for function call
1.235 + asm("b memmove ");
1.236 + }
1.237 +
1.238 +__NAKED__ EXPORT_C void TBufCBase8::Copy(const TDesC8& /*aDes*/,TInt /*aMaxLength*/)
1.239 +//
1.240 +// Copy from a descriptor.
1.241 +//
1.242 + {
1.243 + asm("ldr r3, [r1], #4 "); // r3 = type/length
1.244 + asm("bic r12, r3, #0xF0000000"); // r12 = length
1.245 + asm("cmp r12, r2 "); // compare with maxlength
1.246 + asm("bgt " CSM_Z20Des8PanicDesOverflowv);
1.247 + asm("cmp r3, #0x50000000 ");
1.248 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.249 + asm("eor r3, r3, r3, lsr #1 ");
1.250 + asm("msr cpsr_flg, r3 ");
1.251 + asm("addcs r1, r1, #4 ");
1.252 + asm("ldrle r1, [r1] ");
1.253 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.254 + asm("str r12, [r0], #4 "); // store length/type, r0->buffer
1.255 + asm("mov r2, r12 "); // length into r2 for function call
1.256 + asm("b memmove ");
1.257 + }
1.258 +
1.259 +#ifndef __EABI_CTORS__
1.260 +__NAKED__ EXPORT_C TBufBase8::TBufBase8(TInt /*aMaxLength*/)
1.261 + {
1.262 + asm("mov r2, #0x30000000 "); // EBuf + zero length
1.263 + asm("str r2, [r0] ");
1.264 + asm("str r1, [r0, #4] ");
1.265 + __JUMP(,lr);
1.266 + }
1.267 +
1.268 +__NAKED__ EXPORT_C TBufBase8::TBufBase8(TInt /*aLength*/, TInt /*aMaxLength*/)
1.269 + {
1.270 + asm("cmp r1, #0 "); // check length>=0
1.271 + asm("cmpge r2, r1 "); // if so, check maxlength>=length
1.272 + asm("orrge r1, r1, #0x30000000 "); // r1=length + EBuf
1.273 + asm("stmgeia r0, {r1,r2} "); // store length/type and maxlength fields
1.274 + __JUMP(ge,lr);
1.275 + asm("cmp r2, #0 ");
1.276 + asm("bmi " CSM_Z26Des8PanicMaxLengthNegativev);
1.277 + asm("b " CSM_Z25Des8PanicLengthOutOfRangev);
1.278 + }
1.279 +
1.280 +__NAKED__ EXPORT_C TBufBase8::TBufBase8(const TUint8* /*aString*/, TInt /*aMaxLength*/)
1.281 + {
1.282 + asm("mov r12, r1 "); // save aString pointer
1.283 + asm("1: ");
1.284 + asm("ldrb r3, [r1], #1 ");
1.285 + asm("cmp r3, #0 ");
1.286 + asm("bne 1b "); // loop until we reach zero terminator
1.287 + asm("sub r1, r1, r12 "); // r1 = length + 1
1.288 + asm("sub r1, r1, #1 "); // r1 = length
1.289 + asm("cmp r1, r2 "); // compare to max length
1.290 + asm("bgt " CSM_Z25Des8PanicLengthOutOfRangev); // length too big, so panic
1.291 + asm("orr r1, r1, #0x30000000 "); // if length<=max, r1=EBuf + length
1.292 + asm("stmfd sp!, {r0,lr} "); // save registers for function call
1.293 + asm("stmia r0!, {r1, r2} "); // store type/length and max length fields, r0->buffer
1.294 + asm("bic r2, r1, #0xf0000000 "); // r2=length
1.295 + asm("mov r1, r12 "); // r12=aString
1.296 + asm("bl memmove ");
1.297 + __POPRET("r0,");
1.298 + }
1.299 +
1.300 +__NAKED__ EXPORT_C TBufBase8::TBufBase8(const TDesC8& /*aDes*/, TInt /*aMaxLength*/)
1.301 + {
1.302 + asm("ldr r3, [r1], #4 "); // r3 = type/length
1.303 + asm("bic r12, r3, #0xF0000000"); // r12 = length
1.304 + asm("cmp r12, r2 "); // compare with maxlength
1.305 + asm("bgt " CSM_Z25Des8PanicLengthOutOfRangev);
1.306 + asm("cmp r3, #0x50000000 ");
1.307 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.308 + asm("eor r3, r3, r3, lsr #1 ");
1.309 + asm("msr cpsr_flg, r3 ");
1.310 + asm("addcs r1, r1, #4 ");
1.311 + asm("ldrle r1, [r1] ");
1.312 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.313 + asm("stmfd sp!, {r0,lr} "); // save registers for function call
1.314 + asm("orr r12, r12, #0x30000000 "); // add EBuf type field
1.315 + asm("str r12, [r0], #4 "); // store length/type, r0->max length
1.316 + asm("str r2, [r0], #4 "); // store max length, r0->buffer
1.317 + asm("bic r2, r12, #0xf0000000 "); // length into r2 for function call
1.318 + asm("bl memmove ");
1.319 + __POPRET("r0,");
1.320 + }
1.321 +#endif
1.322 +
1.323 +__NAKED__ EXPORT_C void TDes8::SetLength(TInt /*aLength*/)
1.324 +//
1.325 +// Set the length of the descriptor, checking the length is O.K.
1.326 +//
1.327 + {
1.328 + asm("ldmia r0, {r2,r3} "); // r2=length/type, r3=maxlength
1.329 + asm("cmp r1, r3 "); // check aLength against maxlength and for -ve values
1.330 + asm("bhi " CSM_Z20Des8PanicDesOverflowv);
1.331 + asm("and r2, r2, #0xF0000000 "); // r2=type field
1.332 + asm("cmp r2, #0x40000000 "); // check for EBufCPtr
1.333 + asm("orr r2, r2, r1 "); // r2=type + new length
1.334 + asm("str r2, [r0] "); // store new length
1.335 + __JUMP(ne,lr);
1.336 + asm("ldr r2, [r0, #8] "); // r2=pointer to TBufCBase
1.337 + asm("str r1, [r2] "); // update length of TBufCBase
1.338 + __JUMP(,lr);
1.339 + }
1.340 +
1.341 +__NAKED__ EXPORT_C void TDes8::SetMax()
1.342 +//
1.343 +// Set the length to MaxLength().
1.344 +//
1.345 + {
1.346 + asm("ldmia r0, {r1,r2} "); // r1=length/type, r2=maxlength
1.347 + asm("and r1, r1, #0xF0000000 "); // r1=type field
1.348 + asm("cmp r1, #0x40000000 "); // check for EBufCPtr
1.349 + asm("orr r1, r1, r2 "); // r1=type field + maxlength
1.350 + asm("str r1, [r0] "); // store new length
1.351 + __JUMP(ne,lr);
1.352 + asm("ldr r1, [r0, #8] "); // r1 = pointer to TBufCBase
1.353 + asm("str r2, [r1] "); // update length of TBufCBase
1.354 + __JUMP(,lr);
1.355 + }
1.356 +
1.357 +__NAKED__ EXPORT_C void TDes8::Copy(const TUint8* /*aString*/)
1.358 +//
1.359 +// Copy a string to this descriptor.
1.360 +//
1.361 + {
1.362 + asm("mov r2, r1 "); // r2=aString
1.363 + asm("1: ");
1.364 + asm("ldrb r3, [r2], #1 ");
1.365 + asm("cmp r3, #0 ");
1.366 + asm("bne 1b "); // loop until zero terminator reached
1.367 + asm("sub r2, r2, r1 ");
1.368 + asm("sub r2, r2, #1 "); // r2=length of string
1.369 + asm("ldmia r0, {r3,r12} "); // r3=type/length of this, r12=maxlength
1.370 + asm("cmp r2, r12 "); // compare new length against maxlength
1.371 + asm("bgt " CSM_Z20Des8PanicDesOverflowv);
1.372 + asm("cmp r3, #0x50000000 ");
1.373 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.374 + asm("and r3, r3, #0xF0000000 "); // r3=type of this
1.375 + asm("orr r3, r3, r2 "); // r3=new type/length
1.376 + asm("str r3, [r0], #4 "); // store it
1.377 + asm("eor r3, r3, r3, lsr #1 ");
1.378 + asm("msr cpsr_flg, r3 ");
1.379 + asm("addcs r0, r0, #4 ");
1.380 + asm("ldrle r0, [r0] ");
1.381 + asm("streq r2, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr()
1.382 + asm("b memmove ");
1.383 + }
1.384 +
1.385 +__NAKED__ EXPORT_C void TDes8::Copy(const TUint8* /*aBuf*/,TInt /*aLength*/)
1.386 +//
1.387 +// Copy the aLength characters to the descriptor.
1.388 +//
1.389 + {
1.390 + asm("ldmia r0, {r3,r12} "); // r3=type/length of this, r12=maxlength
1.391 + asm("cmp r2, r12 "); // compare new length against maxlength
1.392 + asm("bhi " CSM_Z20Des8PanicDesOverflowv); // Des8Panic if >MaxLength or -ve
1.393 + asm("cmp r3, #0x50000000 ");
1.394 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.395 + asm("and r3, r3, #0xF0000000 "); // r3=type of this
1.396 + asm("orr r3, r3, r2 "); // r3=new type/length
1.397 + asm("str r3, [r0], #4 "); // store it
1.398 + asm("eor r3, r3, r3, lsr #1 ");
1.399 + asm("msr cpsr_flg, r3 ");
1.400 + asm("addcs r0, r0, #4 ");
1.401 + asm("ldrle r0, [r0] ");
1.402 + asm("streq r2, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr()
1.403 + asm("b memmove ");
1.404 + }
1.405 +
1.406 +__NAKED__ EXPORT_C void TDes8::Copy(const TDesC8& /*aDes*/)
1.407 +//
1.408 +// Copy a descriptor to this descriptor.
1.409 +//
1.410 + {
1.411 + asm("ldr r3, [r1], #4 "); // r3 = type/length of aDes
1.412 + asm("bic r12, r3, #0xF0000000"); // r12 = aDes.length
1.413 + asm("ldr r2, [r0, #4] "); // r2=this.maxlength
1.414 + asm("cmp r12, r2 "); // compare with maxlength
1.415 + asm("bgt " CSM_Z20Des8PanicDesOverflowv);
1.416 + asm("ldr r2, [r0] "); // get type of this
1.417 + asm("cmp r2, #0x50000000 "); // check both descriptor types
1.418 + asm("cmpcc r3, #0x50000000 ");
1.419 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.420 + asm("and r2, r2, #0xF0000000 ");
1.421 + asm("orr r2, r12, r2 "); // r2=new type/length of this
1.422 + asm("str r2, [r0], #4 "); // store it
1.423 + asm("eor r3, r3, r3, lsr #1 ");
1.424 + asm("msr cpsr_flg, r3 ");
1.425 + asm("addcs r1, r1, #4 ");
1.426 + asm("ldrle r1, [r1] ");
1.427 + asm("addeq r1, r1, #4 "); // r1 = aDes.Ptr()
1.428 + asm("eor r2, r2, r2, lsr #1 ");
1.429 + asm("msr cpsr_flg, r2 ");
1.430 + asm("addcs r0, r0, #4 ");
1.431 + asm("ldrle r0, [r0] ");
1.432 + asm("streq r12, [r0], #4 "); // if EBufCPtr, update length of TBufCBase, r0=Ptr()
1.433 + asm("mov r2, r12 "); // length into r2 for function call
1.434 + asm("b memmove ");
1.435 + }
1.436 +
1.437 +#ifndef __KERNEL_MODE__
1.438 +__NAKED__ EXPORT_C TPtr8 TDes8::LeftTPtr(TInt /*aLength*/) const
1.439 +//
1.440 +// Extract the left portion of the descriptor.
1.441 +//
1.442 + {
1.443 + // On entry r0=return store ptr, r1=this, r2=aLength
1.444 + // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr)
1.445 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.446 + asm("cmp r2, #0 "); // check aLength>=0
1.447 + asm("blt Des8PanicPosOutOfRange__Fv "); // if not panic
1.448 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.449 + asm("cmp r2, r12 "); // limit aLength to Length()
1.450 + asm("movgt r2, r12 ");
1.451 + asm("cmp r3, #0x50000000 "); // check type() <= 4
1.452 + asm("bcs Des8PanicBadDesType__Fv "); // if not, panic
1.453 + asm("eor r3, r3, r3, lsr #1 ");
1.454 + asm("msr cpsr_flg, r3 ");
1.455 + asm("addcs r1, r1, #4 ");
1.456 + asm("ldrle r1, [r1] ");
1.457 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.458 + asm("mov r3, r1 "); // r3=this.Ptr()
1.459 + asm("orr r1, r2, #0x20000000 "); // r1=aLength + EPtr
1.460 + asm("stmia r0, {r1-r3} ");
1.461 + __JUMP(,lr);
1.462 + }
1.463 +
1.464 +__NAKED__ EXPORT_C TPtr8 TDes8::RightTPtr(TInt /*aLength*/) const
1.465 +//
1.466 +// Extract the right portion of the descriptor.
1.467 +//
1.468 + {
1.469 + // On entry r0=return store ptr, r1=this, r2=aLength
1.470 + // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr)
1.471 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.472 + asm("cmp r2, #0 "); // check aLength>=0
1.473 + asm("blt Des8PanicPosOutOfRange__Fv "); // if not, panic
1.474 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.475 + asm("cmp r2, r12 "); // limit aLength to Length()
1.476 + asm("movgt r2, r12 ");
1.477 + asm("cmp r3, #0x50000000 "); // check type() <= 4
1.478 + asm("bcs Des8PanicBadDesType__Fv ");
1.479 + asm("eor r3, r3, r3, lsr #1 ");
1.480 + asm("msr cpsr_flg, r3 ");
1.481 + asm("addcs r1, r1, #4 ");
1.482 + asm("ldrle r1, [r1] ");
1.483 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.484 + asm("add r3, r1, r12 "); // r3=this.Ptr()+Length()
1.485 + asm("orr r1, r2, #0x20000000 "); // r1=aLength + EPtr
1.486 + asm("sub r3, r3, r2 "); // r3=Ptr()+Length()-aLength
1.487 + asm("stmia r0, {r1-r3} ");
1.488 + __JUMP(,lr);
1.489 + }
1.490 +
1.491 +__NAKED__ EXPORT_C TPtr8 TDes8::MidTPtr(TInt /*aPos*/) const
1.492 +//
1.493 +// Extract the middle portion of the descriptor.
1.494 +//
1.495 + {
1.496 + // On entry r0=return store ptr, r1=this, r2=aPos
1.497 + // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr)
1.498 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.499 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.500 + asm("cmp r2, #0 "); // check aPos>=0
1.501 + asm("cmpge r12, r2 "); // if so check Length()>=aPos
1.502 + asm("blt Des8PanicPosOutOfRange__Fv ");
1.503 + asm("cmp r3, #0x50000000 "); // check type() <= 4
1.504 + asm("bcs Des8PanicBadDesType__Fv ");
1.505 + asm("eor r3, r3, r3, lsr #1 ");
1.506 + asm("msr cpsr_flg, r3 ");
1.507 + asm("addcs r1, r1, #4 ");
1.508 + asm("ldrle r1, [r1] ");
1.509 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.510 + asm("add r3, r1, r2 "); // r3=this.Ptr()+aPos
1.511 + asm("sub r2, r12, r2 "); // r2=Length()-aPos (=newMaxLen)
1.512 + asm("orr r1, r2, #0x20000000 "); // r1=Length()-aPos + EPtr (=newLen/Type)
1.513 + asm("stmia r0, {r1-r3} ");
1.514 + __JUMP(,lr);
1.515 + }
1.516 +
1.517 +__NAKED__ EXPORT_C TPtr8 TDes8::MidTPtr(TInt /*aPos*/,TInt /*aLength*/) const
1.518 +//
1.519 +// Extract the middle portion of the descriptor.
1.520 +//
1.521 + {
1.522 + // On entry r0=return store ptr, r1=this, r2=aPos, r3=aLength
1.523 + // Return TPtr8 ([r0]=length/type,[r0,#4]=maxLength,[r0,#8]=Ptr)
1.524 + asm("str r4, [sp, #-4]! "); // save r4
1.525 + asm("ldr r12, [r1], #4 "); // r12=this.length/type
1.526 + asm("mov r4, r1 ");
1.527 + asm("cmp r12, #0x50000000 "); // check valid descriptor type
1.528 + asm("bcs Des8PanicBadDesType__Fv ");
1.529 + asm("eor r12, r12, r12, lsr #1 ");
1.530 + asm("msr cpsr_flg, r12 ");
1.531 + asm("ldr r12, [r1, #-4] ");
1.532 + asm("addcs r4, r4, #4 ");
1.533 + asm("ldrle r4, [r4] ");
1.534 + asm("bic r12, r12, #0xF0000000 "); // r12=Length()
1.535 + asm("addeq r4, r4, #4 "); // r4=this.Ptr()
1.536 + asm("cmp r2, #0 "); // check aPos>=0
1.537 + asm("subge r12, r12, r2 "); // if so, r12=Length()-aPos
1.538 + asm("cmpge r12, r3 "); // and check Length()-aPos>=aLength
1.539 + asm("orrge r1, r3, #0x20000000 "); // if so, r1=aLength + EPtr
1.540 + asm("addge r3, r4, r2 "); // and r3=this.Ptr()+aPos
1.541 + asm("bicge r2, r1, #0xF0000000 "); // and r2=aLength
1.542 + asm("stmgeia r0, {r1-r3} ");
1.543 + asm("ldrge r4, [sp], #4 ");
1.544 + __JUMP(ge,lr);
1.545 + asm("b Des8PanicPosOutOfRange__Fv ");
1.546 + }
1.547 +#endif
1.548 +
1.549 +__NAKED__ EXPORT_C const TUint8 &TDesC8::AtC(TInt /*anIndex*/) const
1.550 +//
1.551 +// Return a reference to the character in the buffer.
1.552 +//
1.553 + {
1.554 + asm("ldr r2, [r0], #4 "); // r2=length/type
1.555 + asm("bic r3, r2, #0xF0000000 "); // r3=length
1.556 + asm("cmp r2, #0x50000000 ");
1.557 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.558 + asm("eor r2, r2, r2, lsr #1 ");
1.559 + asm("msr cpsr_flg, r2 ");
1.560 + asm("addcs r0, r0, #4 ");
1.561 + asm("ldrle r0, [r0] ");
1.562 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.563 + asm("cmp r1, #0 "); // check index>=0
1.564 + asm("cmpge r3, r1 "); // if so, check Length()>index
1.565 + asm("addgt r0, r0, r1 "); // return value = this.Ptr()+index
1.566 + __JUMP(gt,lr);
1.567 + asm("b " CSM_Z27Des8PanicDesIndexOutOfRangev);
1.568 + }
1.569 +
1.570 +__NAKED__ EXPORT_C TInt TDesC8::Locate(TChar /*aChar*/) const
1.571 +//
1.572 +// Locate character aChar in the descriptor.
1.573 +//
1.574 + {
1.575 + asm("ldr r2, [r0], #4 "); // r2=length/type
1.576 + asm("cmp r2, #0x50000000 ");
1.577 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.578 + asm("bics r3, r2, #0xF0000000 "); // r3=length
1.579 + asm("mvneq r0, #0 "); // if length=0, not found
1.580 + __JUMP(eq,lr);
1.581 + asm("eor r2, r2, r2, lsr #1 ");
1.582 + asm("msr cpsr_flg, r2 ");
1.583 + asm("addcs r0, r0, #4 ");
1.584 + asm("ldrle r0, [r0] ");
1.585 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.586 + asm("add r3, r3, r0 "); // r3=ptr+length
1.587 + asm("add r12, r0, #1 "); // r12=ptr+1
1.588 + asm("1: ");
1.589 + asm("ldrb r2, [r0], #1 "); // r2=*r0++
1.590 + asm("cmp r1, r2 "); // is r1=match char?
1.591 + asm("cmpne r0, r3 "); // if not, is r0=r3 (end pointer)
1.592 + asm("bne 1b ");
1.593 + asm("cmp r1, r2 "); // did we find char?
1.594 + asm("subeq r0, r0, r12 "); // if we did, return value = r0-ptr-1
1.595 + asm("mvnne r0, #0 "); // else return value =-1
1.596 + __JUMP(,lr);
1.597 + }
1.598 +
1.599 +__NAKED__ EXPORT_C TInt TDesC8::LocateReverse(TChar /*aChar*/) const
1.600 +//
1.601 +// Locate character aChar in the descriptor in reverse.
1.602 +//
1.603 + {
1.604 + asm("ldr r2, [r0], #4 "); // r2=length/type
1.605 + asm("cmp r2, #0x50000000 ");
1.606 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.607 + asm("bics r3, r2, #0xF0000000 "); // r3=length
1.608 + asm("mvneq r0, #0 "); // if length=0, not found
1.609 + __JUMP(eq,lr);
1.610 + asm("eor r2, r2, r2, lsr #1 ");
1.611 + asm("msr cpsr_flg, r2 ");
1.612 + asm("addcs r0, r0, #4 ");
1.613 + asm("ldrle r0, [r0] ");
1.614 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.615 + asm("sub r0, r0, #1 "); // r0=Ptr-1
1.616 + asm("1: ");
1.617 + asm("ldrb r2, [r0, r3] "); // r2=Ptr[r3-1]
1.618 + asm("cmp r1, r2 "); // is r1=match char?
1.619 + asm("subnes r3, r3, #1 "); // if not, decrement char count
1.620 + asm("bne 1b ");
1.621 + asm("cmp r1, r2 "); // did we find match char?
1.622 + asm("subeq r0, r3, #1 "); // if we did, return value = r3-1
1.623 + asm("mvnne r0, #0 "); // else return value =-1
1.624 + __JUMP(,lr);
1.625 + }
1.626 +
1.627 +#ifndef __KERNEL_MODE__
1.628 +__NAKED__ EXPORT_C TInt TDesC8::CompareF(const TDesC8& /*aDes*/) const
1.629 +//
1.630 +// Compare a descriptor to this descriptor folded.
1.631 +//
1.632 + {
1.633 + asm("ldr r12, 1f ");
1.634 + asm("b comparebody ");
1.635 + asm("1: ");
1.636 + asm(".word " CSM_ZN3Mem8CompareFEPKhiS0_i);
1.637 + }
1.638 +
1.639 +__NAKED__ EXPORT_C TInt TDesC8::CompareC(const TDesC8& /*aDes*/) const
1.640 +//
1.641 +// Compare a descriptor to this descriptor collated.
1.642 +//
1.643 + {
1.644 + asm("ldr r12, 1f ");
1.645 + asm("b comparebody ");
1.646 + asm("1: ");
1.647 + asm(".word " CSM_ZN3Mem8CompareCEPKhiS0_i);
1.648 + }
1.649 +#endif
1.650 +
1.651 +__NAKED__ EXPORT_C TInt TDesC8::Compare(const TDesC8& /*aDes*/) const
1.652 +//
1.653 +// Compare a descriptor to this descriptor.
1.654 +//
1.655 + {
1.656 + asm("ldr r12, 1f ");
1.657 + asm("comparebody: ");
1.658 + asm("mov r2, r1 "); // r2=&aDes
1.659 + asm("ldr r3, [r0], #4 "); // r3=this.length/type
1.660 + asm("cmp r3, #0x50000000 ");
1.661 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.662 + asm("bic r1, r3, #0xF0000000 "); // r1=this.Length()
1.663 + asm("eor r3, r3, r3, lsr #1 ");
1.664 + asm("msr cpsr_flg, r3 ");
1.665 + asm("addcs r0, r0, #4 ");
1.666 + asm("ldrle r0, [r0] ");
1.667 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.668 + asm("ldr r3, [r2], #4 "); // r3=aDes.length/type
1.669 + asm("cmp r3, #0x50000000 ");
1.670 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.671 + asm("eor r3, r3, r3, lsr #1 ");
1.672 + asm("msr cpsr_flg, r3 ");
1.673 + asm("ldr r3, [r2, #-4] ");
1.674 + asm("bic r3, r3, #0xF0000000 "); // r3=aDes.Length()
1.675 + asm("addcs r2, r2, #4 ");
1.676 + asm("ldrle r2, [r2] ");
1.677 + asm("addeq r2, r2, #4 "); // r2=aDes.Ptr()
1.678 + __JUMP(,r12);
1.679 +
1.680 + asm("1: ");
1.681 + asm(".word memcompare ");
1.682 + }
1.683 +#endif // __DES8_MACHINE_CODED__
1.684 +
1.685 +#if defined(__DES8_MACHINE_CODED__) && !defined(__EABI__)
1.686 +__NAKED__ EXPORT_C TPtrC8 TDesC8::Left(TInt /*aLength*/) const
1.687 +//
1.688 +// Extract the left portion of the descriptor.
1.689 +//
1.690 + {
1.691 + // On entry r0=this, r1=aLength
1.692 + // Return TPtrC8 in r0,r1
1.693 + asm("ldr r3, [r0], #4 "); // r3=this.length/type
1.694 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.695 + asm("cmp r1, #0 "); // check aLength>=0
1.696 + asm("blt " CSM_Z22Des8PanicPosOutOfRangev); // if not panic
1.697 + asm("cmp r1, r12 "); // else limit aLength to Length()
1.698 + asm("movgt r1, r12 ");
1.699 + asm("cmp r3, #0x50000000 ");
1.700 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.701 + asm("eor r3, r3, r3, lsr #1 ");
1.702 + asm("msr cpsr_flg, r3 ");
1.703 + asm("addcs r0, r0, #4 ");
1.704 + asm("ldrle r0, [r0] ");
1.705 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.706 + asm("orr r2, r1, #0x10000000 "); // r2=aLength + EPtrC
1.707 + asm("mov r1, r0 "); // r1=result ptr
1.708 + asm("mov r0, r2 "); // r0=result type/length
1.709 + __JUMP(,lr);
1.710 + }
1.711 +
1.712 +__NAKED__ EXPORT_C TPtrC8 TDesC8::Right(TInt /*aLength*/) const
1.713 +//
1.714 +// Extract the right portion of the descriptor.
1.715 +//
1.716 + {
1.717 + // On entry r0=this, r1=aLength
1.718 + // Return TPtrC8 in r0,r1
1.719 + asm("ldr r3, [r0], #4 "); // r3=this.length/type
1.720 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.721 + asm("cmp r1, #0 "); // check aLength>=0
1.722 + asm("blt " CSM_Z22Des8PanicPosOutOfRangev); // if not, panic
1.723 + asm("cmp r1, r12 "); // else limit aLength to Length()
1.724 + asm("movgt r1, r12 ");
1.725 + asm("cmp r3, #0x50000000 ");
1.726 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.727 + asm("eor r3, r3, r3, lsr #1 ");
1.728 + asm("msr cpsr_flg, r3 ");
1.729 + asm("addcs r0, r0, #4 ");
1.730 + asm("ldrle r0, [r0] ");
1.731 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.732 + asm("add r3, r0, r12 "); // r3=this.Ptr()+len
1.733 + asm("orr r0, r1, #0x10000000 "); // r0=aLength + EPtrC
1.734 + asm("sub r1, r3, r1 "); // r1=Ptr()+len-aLength
1.735 + __JUMP(,lr);
1.736 + }
1.737 +
1.738 +__NAKED__ EXPORT_C TPtrC8 TDesC8::Mid(TInt /*aPos*/) const
1.739 +//
1.740 +// Extract the middle portion of the descriptor.
1.741 +//
1.742 + {
1.743 + // On entry r0=this, r1=aPos
1.744 + // Return TPtrC8 in r0,r1
1.745 + asm("ldr r3, [r0], #4 "); // r3=this.length/type
1.746 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.747 + asm("cmp r1, #0 "); // check aPos>=0
1.748 + asm("cmpge r12, r1 "); // if so check Length()>=aPos
1.749 + asm("blt " CSM_Z22Des8PanicPosOutOfRangev);
1.750 + asm("cmp r3, #0x50000000 ");
1.751 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.752 + asm("eor r3, r3, r3, lsr #1 ");
1.753 + asm("msr cpsr_flg, r3 ");
1.754 + asm("addcs r0, r0, #4 ");
1.755 + asm("ldrle r0, [r0] ");
1.756 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.757 + asm("sub r2, r12, r1 "); // r2=len-aPos
1.758 + asm("add r1, r0, r1 "); // r1=this.Ptr()+aPos
1.759 + asm("orr r0, r2, #0x10000000 "); // r0=aLength + EPtrC
1.760 + __JUMP(,lr);
1.761 + }
1.762 +
1.763 +__NAKED__ EXPORT_C TPtrC8 TDesC8::Mid(TInt /*aPos*/,TInt /*aLength*/) const
1.764 +//
1.765 +// Extract the middle portion of the descriptor.
1.766 +//
1.767 + {
1.768 + // On entry r0=this, r1=aPos, r2=aLength
1.769 + // Return TPtrC8 in r0,r1
1.770 + asm("ldr r12, [r0], #4 "); // r12=this.length/type
1.771 + asm("cmp r12, #0x50000000 "); // check valid descriptor type
1.772 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.773 + asm("eor r12, r12, r12, lsr #1 ");
1.774 + asm("msr cpsr_flg, r12 ");
1.775 + asm("ldr r12, [r0, #-4] ");
1.776 + asm("bic r12, r12, #0xF0000000 "); // r12=Length()
1.777 + asm("addcs r0, r0, #4 ");
1.778 + asm("ldrle r0, [r0] ");
1.779 + asm("addeq r0, r0, #4 "); // r0=this.Ptr()
1.780 + asm("cmp r1, #0 "); // check aPos>=0
1.781 + asm("subge r12, r12, r1 "); // if so, r12=Length()-aPos
1.782 + asm("cmpge r12, r2 "); // and check Length()-aPos>=aLength
1.783 + asm("addge r1, r1, r0 "); // if so, r1=Ptr()+aPos
1.784 + asm("orrge r0, r2, #0x10000000 "); // and r0 = aLength + EPtrC
1.785 + __JUMP(ge,lr);
1.786 + asm("b " CSM_Z22Des8PanicPosOutOfRangev);
1.787 + }
1.788 +#endif // defined(__DES8_MACHINE_CODED__) && !defined(__EABI__)
1.789 +
1.790 +#ifdef __DES8_MACHINE_CODED__
1.791 +
1.792 +// Here are the __EABI__ compliant versions of the above
1.793 +#ifdef __EABI__
1.794 +
1.795 +__NAKED__ EXPORT_C TPtrC8 TDesC8::Left(TInt /*aLength*/) const
1.796 +//
1.797 +// Extract the left portion of the descriptor.
1.798 +//
1.799 + {
1.800 + // On entry r0=return store ptr, r1=this, r2=aLength
1.801 + // Return TPtrC8 ([r0]=length/type,[r0,#4]=Ptr)
1.802 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.803 + asm("cmp r2, #0 "); // check aLength>=0
1.804 + asm("blt Des8PanicPosOutOfRange__Fv "); // if not panic
1.805 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.806 + asm("cmp r2, r12 "); // limit aLength to Length()
1.807 + asm("movgt r2, r12 ");
1.808 + asm("cmp r3, #0x50000000 "); // check type() <= 4
1.809 + asm("bcs Des8PanicBadDesType__Fv "); // if not, panic
1.810 + asm("eor r3, r3, r3, lsr #1 ");
1.811 + asm("msr cpsr_flg, r3 ");
1.812 + asm("addcs r1, r1, #4 ");
1.813 + asm("ldrle r1, [r1] ");
1.814 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.815 + asm("mov r3, r1"); // r3=this.Ptr()
1.816 + asm("orr r1, r2, #0x10000000 "); // r1=aLength + EPtrC
1.817 + asm("stmia r0, {r1,r3} ");
1.818 + __JUMP(,lr);
1.819 + }
1.820 +
1.821 +__NAKED__ EXPORT_C TPtrC8 TDesC8::Right(TInt /*aLength*/) const
1.822 +//
1.823 +// Extract the right portion of the descriptor.
1.824 +//
1.825 + {
1.826 + // On entry r0=return store ptr, r1=this, r2=aLength
1.827 + // Return TPtrC8 ([r0]=length/type,[r0,#4]=Ptr)
1.828 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.829 + asm("cmp r2, #0 "); // check aLength>=0
1.830 + asm("blt Des8PanicPosOutOfRange__Fv "); // if not, panic
1.831 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.832 + asm("cmp r2, r12 "); // limit aLength to Length()
1.833 + asm("movgt r2, r12 ");
1.834 + asm("cmp r3, #0x50000000 "); // check type() <= 4
1.835 + asm("bcs Des8PanicBadDesType__Fv ");
1.836 + asm("eor r3, r3, r3, lsr #1 ");
1.837 + asm("msr cpsr_flg, r3 ");
1.838 + asm("addcs r1, r1, #4 ");
1.839 + asm("ldrle r1, [r1] ");
1.840 + asm("addeq r1, r1, #4 "); // r3=this.Ptr()
1.841 + asm("add r3, r1, r12 "); // r3=this.Ptr()+Length()
1.842 + asm("orr r1, r2, #0x10000000 "); // r1=aLength + EPtrC
1.843 + asm("sub r3, r3, r2 "); // r3=Ptr()+Length()-aLength
1.844 + asm("stmia r0, {r1,r3} ");
1.845 + __JUMP(,lr);
1.846 + }
1.847 +
1.848 +__NAKED__ EXPORT_C TPtrC8 TDesC8::Mid(TInt /*aPos*/) const
1.849 +//
1.850 +// Extract the middle portion of the descriptor.
1.851 +//
1.852 + {
1.853 + // On entry r0=return store ptr, r1=this, r2=aPos
1.854 + // Return TPtrC8 ([r0]=length/type,[r0,#4]=Ptr)
1.855 + asm("ldr r3, [r1], #4 "); // r3=this.length/type
1.856 + asm("bic r12, r3, #0xF0000000 "); // r12=this.Length()
1.857 + asm("cmp r2, #0 "); // check aPos>=0
1.858 + asm("cmpge r12, r2 "); // if so check Length()>=aPos
1.859 + asm("blt Des8PanicPosOutOfRange__Fv ");
1.860 + asm("cmp r3, #0x50000000 "); // check type() <= 4
1.861 + asm("bcs Des8PanicBadDesType__Fv ");
1.862 + asm("eor r3, r3, r3, lsr #1 ");
1.863 + asm("msr cpsr_flg, r3 ");
1.864 + asm("addcs r1, r1, #4 ");
1.865 + asm("ldrle r1, [r1] ");
1.866 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.867 + asm("add r3, r1, r2 "); // r3=this.Ptr()+aPos
1.868 + asm("sub r2, r12, r2 "); // r2=Length()-aPos (=newMaxLen)
1.869 + asm("orr r1, r2, #0x10000000 "); // r1=Length()-aPos + EPtrC (=newLen/Type)
1.870 + asm("stmia r0, {r1,r3} ");
1.871 + __JUMP(,lr);
1.872 + }
1.873 +
1.874 +__NAKED__ EXPORT_C TPtrC8 TDesC8::Mid(TInt /*aPos*/,TInt /*aLength*/) const
1.875 +//
1.876 +// Extract the middle portion of the descriptor.
1.877 +//
1.878 + {
1.879 + // On entry r0=return store ptr, r1=this, r2=aPos, r3=aLength
1.880 + // Return TPtrC8 ([r0]=length/type,[r0,#4]=Ptr)
1.881 + asm("ldr r12, [r1], #4 "); // r12=this.length/type
1.882 + asm("cmp r12, #0x50000000 "); // check valid descriptor type
1.883 + asm("bcs Des8PanicBadDesType__Fv ");
1.884 + asm("eor r12, r12, r12, lsr #1 ");
1.885 + asm("msr cpsr_flg, r12 ");
1.886 + asm("ldr r12, [r1, #-4] ");
1.887 + asm("addcs r1, r1, #4 ");
1.888 + asm("ldrle r1, [r1] ");
1.889 + asm("bic r12, r12, #0xF0000000 "); // r12=Length()
1.890 + asm("addeq r1, r1, #4 "); // r1=this.Ptr()
1.891 + asm("cmp r2, #0 "); // check aPos>=0
1.892 + asm("subge r12, r12, r2 "); // if so, r12=Length()-aPos
1.893 + asm("cmpge r12, r3 "); // and check Length()-aPos>=aLength
1.894 + asm("addge r2, r1, r2 "); // if so r2=this.Ptr()+aPos
1.895 + asm("orrge r1, r3, #0x10000000 "); // and r1=aLength + EPtrC
1.896 + asm("stmgeia r0, {r1,r2} ");
1.897 + __JUMP(ge,lr);
1.898 + asm("b Des8PanicPosOutOfRange__Fv ");
1.899 + }
1.900 +#endif
1.901 +
1.902 +__NAKED__ EXPORT_C void TDes8::Zero()
1.903 +//
1.904 +// Zero the buffer.
1.905 +//
1.906 + {
1.907 + asm("ldr r1, [r0] "); // r1=length/type
1.908 + asm("and r1, r1, #0xF0000000 "); // r1=type field, zero length
1.909 + asm("cmp r1, #0x40000000 "); // check for EBufCPtr
1.910 + asm("str r1, [r0] "); // store zero length
1.911 + __JUMP(ne,lr);
1.912 + asm("ldr r2, [r0, #8] "); // r2 = pointer to TBufCBase
1.913 + asm("mov r1, #0 ");
1.914 + asm("str r1, [r2] "); // update length of TBufCBase
1.915 + __JUMP(,lr);
1.916 + }
1.917 +
1.918 +#ifndef __KERNEL_MODE__
1.919 +__NAKED__ EXPORT_C void TDes8::ZeroTerminate()
1.920 +//
1.921 +// Zero terminate at Length().
1.922 +//
1.923 + {
1.924 + // Fall through to PtrZ below...
1.925 + }
1.926 +
1.927 +__NAKED__ EXPORT_C const TUint8 *TDes8::PtrZ()
1.928 +//
1.929 +// Return a pointer to a 0 terminated string.
1.930 +//
1.931 + {
1.932 + asm("ldmia r0, {r1,r2} "); // r1=length/type, r2=maxlength
1.933 + asm("bic r3, r1, #0xF0000000 "); // r3=Length();
1.934 + asm("cmp r3, r2 "); // check Length()<MaxLength()
1.935 + asm("bge " CSM_Z20Des8PanicDesOverflowv);
1.936 + asm("cmp r1, #0x50000000 ");
1.937 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.938 + asm("eor r1, r1, r1, lsr #1 ");
1.939 + asm("msr cpsr_flg, r1 ");
1.940 + asm("add r0, r0, #4 ");
1.941 + asm("addcs r0, r0, #4 ");
1.942 + asm("ldrle r0, [r0] ");
1.943 + asm("addeq r0, r0, #4 "); // r0=Ptr()
1.944 + asm("mov r2, #0 ");
1.945 + asm("strb r2, [r0, r3] "); // Ptr()[Length()]=0;
1.946 + __JUMP(,lr);
1.947 + }
1.948 +#endif
1.949 +
1.950 +__NAKED__ EXPORT_C void TDes8::Append(TChar /*aChar*/)
1.951 +//
1.952 +// Add a character at the end of the string.
1.953 +//
1.954 + {
1.955 + asm("ldmia r0, {r2,r3} "); // r2=length/type, r3=maxlength
1.956 + asm("bic r12, r2, #0xF0000000 "); // r12=Length();
1.957 + asm("cmp r12, r3 "); // check Length()<MaxLength()
1.958 + asm("bge " CSM_Z20Des8PanicDesOverflowv);
1.959 + asm("cmp r2, #0x50000000 ");
1.960 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.961 + asm("add r2, r2, #1 "); // increment length by 1
1.962 + asm("str r2, [r0] "); // store new length
1.963 + asm("eor r2, r2, r2, lsr #1 ");
1.964 + asm("msr cpsr_flg, r2 ");
1.965 + asm("add r2, r0, #4 "); // r2=this+4
1.966 + asm("addcs r2, r2, #4 ");
1.967 + asm("ldrle r2, [r2] ");
1.968 + asm("addeq r3, r12, #1 "); // if EBufCPtr, r3=Length()+1
1.969 + asm("streq r3, [r2], #4 "); // and update length of TBufCBase, r2=Ptr()
1.970 + asm("strb r1, [r2, r12] "); // Ptr()[Length()]=aChar;
1.971 + __JUMP(,lr);
1.972 + }
1.973 +
1.974 +__NAKED__ EXPORT_C void TDes8::Append(const TDesC8& /*aDes*/)
1.975 +//
1.976 +// Append a descriptor to this descriptor.
1.977 +//
1.978 + {
1.979 + asm("ldr r3, [r1], #4 "); // r3=aDes.length/type
1.980 + asm("cmp r3, #0x50000000 ");
1.981 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.982 + asm("bics r2, r3, #0xF0000000 "); // r2=aDes.Length()
1.983 + __JUMP(eq,lr);
1.984 + asm("eor r3, r3, r3, lsr #1 ");
1.985 + asm("msr cpsr_flg, r3 ");
1.986 + asm("addcs r1, r1, #4 ");
1.987 + asm("ldrle r1, [r1] ");
1.988 + asm("addeq r1, r1, #4 "); // r1=aDes.Ptr()
1.989 + asm("b appendbody "); // use following routine for rest of job
1.990 + }
1.991 +
1.992 +__NAKED__ EXPORT_C void TDes8::Append(const TUint8* /*aBuf*/,TInt /*aLength*/)
1.993 +//
1.994 +// Append aLength from aBuf characters to the descriptor.
1.995 +//
1.996 + {
1.997 + asm("cmp r2, #0 "); // check aLength>=0
1.998 + __JUMP(eq,lr);
1.999 + asm("blt " CSM_Z23Des8PanicLengthNegativev);
1.1000 + asm("appendbody: ");
1.1001 + asm("ldmia r0, {r3,r12} "); // r3=type/length, r12=maxlength
1.1002 + asm("cmp r3, #0x50000000 ");
1.1003 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.1004 + asm("bic r3, r3, #0xF0000000 "); // r3=Length()
1.1005 + asm("sub r12, r12, r3 "); // r12=MaxLength-Length
1.1006 + asm("cmp r2, r12 "); // check aLength<=(MaxLength-Length)
1.1007 + asm("bgt " CSM_Z20Des8PanicDesOverflowv);
1.1008 + asm("ldr r12, [r0] ");
1.1009 + asm("add r12, r12, r2 "); // new length/type field
1.1010 + asm("str r12, [r0], #4 "); // store it
1.1011 + asm("eor r12, r12, r12, lsr #1 ");
1.1012 + asm("msr cpsr_flg, r12 ");
1.1013 + asm("addcs r0, r0, #4 ");
1.1014 + asm("ldrle r0, [r0] ");
1.1015 + asm("ldreq r12, [r0] "); // fetch length from TBufCBase
1.1016 + asm("addeq r12, r12, r2 "); // add aLength
1.1017 + asm("streq r12, [r0], #4 "); // update length of TBufCBase, r0=Ptr()
1.1018 + asm("add r0, r0, r3 "); // r0=Ptr()+Length()
1.1019 + asm("b memmove ");
1.1020 + }
1.1021 +
1.1022 +__NAKED__ EXPORT_C void TDes8::FillZ()
1.1023 +//
1.1024 +// Fill the descriptor with 0.
1.1025 +//
1.1026 + {
1.1027 + asm("ldr r2, [r0] "); // r2=length/type
1.1028 + asm("cmp r2, #0x50000000 ");
1.1029 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.1030 + asm("bic r1, r2, #0xF0000000 "); // r1=Length()
1.1031 + asm("eor r2, r2, r2, lsr #1 ");
1.1032 + asm("msr cpsr_flg, r2 ");
1.1033 + asm("add r0, r0, #4 ");
1.1034 + asm("addcs r0, r0, #4 ");
1.1035 + asm("ldrle r0, [r0] ");
1.1036 + asm("addeq r0, r0, #4 "); // r0=Ptr()
1.1037 + asm("b memclr ");
1.1038 + }
1.1039 +
1.1040 +__NAKED__ EXPORT_C void TDes8::Fill(TChar /*aChar*/)
1.1041 +//
1.1042 +// Fill the descriptor with aChar.
1.1043 +//
1.1044 + {
1.1045 + asm("ldr r3, [r0] "); // r3=length/type
1.1046 + asm("cmp r3, #0x50000000 ");
1.1047 + asm("bcs " CSM_Z19Des8PanicBadDesTypev);
1.1048 + asm("bic r2, r3, #0xF0000000 "); // r2=Length()
1.1049 + asm("eor r3, r3, r3, lsr #1 ");
1.1050 + asm("msr cpsr_flg, r3 ");
1.1051 + asm("add r0, r0, #4 ");
1.1052 + asm("addcs r0, r0, #4 ");
1.1053 + asm("ldrle r0, [r0] ");
1.1054 + asm("addeq r0, r0, #4 "); // r0=Ptr()
1.1055 + asm("b memset "); // memset(Ptr(),aChar,Length())
1.1056 + }
1.1057 +#endif //__DES8_MACHINE_CODED__
1.1058 +
1.1059 +#ifdef __DES_MACHINE_CODED__
1.1060 +__NAKED__ GLDEF_C TInt __DoConvertNum(TUint /*aVal*/, TRadix /*aRadix*/, TUint /*aA*/, TUint8*& /*aDest*/)
1.1061 + {
1.1062 + asm("ldr ip, [r3] "); // ip = aDest
1.1063 + asm("cmp r1, #16 ");
1.1064 + asm("beq do_convert_hex ");
1.1065 + asm("cmp r1, #10 ");
1.1066 + asm("beq do_convert_dec ");
1.1067 +#ifdef __KERNEL_MODE__
1.1068 + asm("mov r0, #%a0" : : "i" ((TInt)EInvalidRadix));
1.1069 + asm("b " CSM_Z5Panic9TCdtPanic);
1.1070 +#else // !__KERNEL_MODE__
1.1071 + asm("cmp r1, #2 ");
1.1072 + asm("beq do_convert_bin ");
1.1073 + asm("cmp r1, #8 ");
1.1074 + asm("beq do_convert_oct ");
1.1075 + asm("do_convert_any: ");
1.1076 + asm("stmfd sp!, {r4-r8,lr} ");
1.1077 + asm("mov r5, r1 "); // save radix
1.1078 + asm("and r6, r2, #0xff ");
1.1079 + asm("sub r6, r6, #10 "); // save aA - 10
1.1080 + asm("mov r4, ip "); // r4 = aDest
1.1081 + asm("mov r7, r3 "); // save &aDest
1.1082 + asm("mov r8, r2"); // save aA
1.1083 + asm("1: ");
1.1084 + asm("mov r1, r5 "); // r1 = radix
1.1085 +#ifndef __EABI__
1.1086 + asm(".extern __umodsi3 ");
1.1087 + asm("bl __umodsi3 "); // do division, quotient->r3, rem->r0
1.1088 + asm("mov r1, r0"); // move to make regs same as EABI function
1.1089 + asm("mov r0, r3");
1.1090 +#else //__EABI__
1.1091 + asm(".extern __aeabi_uidivmod ");
1.1092 + asm("bl __aeabi_uidivmod "); // do division, quotient->r0, rem->r1
1.1093 +#endif //__EABI__
1.1094 + asm("cmp r1, #9 ");
1.1095 + asm("addhi r1, r1, r6 "); // r1 = (r1 > 9) ? (r1 + (aA - 10)) : r1 + '0'
1.1096 + asm("addls r1, r1, #0x30 ");
1.1097 + asm("tst r8, #0x100 ");
1.1098 + asm("strneh r1, [r4, #-2]! "); // *--r4 = (TUint16)r1
1.1099 + asm("streqb r1, [r4, #-1]! "); // *--r4 = (TUint8)r1
1.1100 + asm("movs r1, r0 "); // new aVal into r1
1.1101 + asm("bne 1b ");
1.1102 + asm("ldr ip, [r7] "); // ip can be scratched by __aeabi_uidivmod
1.1103 + asm("str r4, [r7] "); // aDest = r4
1.1104 + asm("sub r0, ip, r4 "); // return aDest - r4
1.1105 + __POPRET("r4-r8,");
1.1106 +
1.1107 + asm("do_convert_bin: ");
1.1108 + asm("mov r2, r2, lsl #22 "); // aA bit 8 into bit 30
1.1109 + asm("adds r2, r2, r2 "); // set V flag = aA bit 8
1.1110 + asm("1: ");
1.1111 + asm("movs r0, r0, lsr #1 "); // aVal>>=1, bit 0 into carry, V unaffected
1.1112 + asm("mov r1, #0x30 "); // r1 = '0'
1.1113 + asm("adc r1, r1, #0 "); // add in carry
1.1114 + asm("strvsh r1, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1115 + asm("strvcb r1, [ip, #-1]! "); // else store 8 bits
1.1116 + asm("bne 1b "); // loop back if aVal still nonzero
1.1117 + asm("ldr r1, [r3] "); // r1 = original aDest
1.1118 + asm("str ip, [r3] "); // aDest = ip
1.1119 + asm("sub r0, r1, ip "); // return aDest - ip
1.1120 + __JUMP(,lr);
1.1121 +
1.1122 + asm("do_convert_oct: ");
1.1123 + asm("mov r2, r2, lsl #22 "); // aA bit 8 into bit 30
1.1124 + asm("adds r2, r2, r2 "); // set V flag = aA bit 8
1.1125 + asm("1: ");
1.1126 + asm("and r1, r0, #7 "); // r1 = aVal & 7
1.1127 + asm("movs r0, r0, lsr #3 "); // aVal>>=3, set Z accordingly, V unaffected
1.1128 + asm("add r1, r1, #0x30 "); // r1 += '0'
1.1129 + asm("strvsh r1, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1130 + asm("strvcb r1, [ip, #-1]! "); // else store 8 bits
1.1131 + asm("bne 1b "); // loop back if aVal still nonzero
1.1132 + asm("ldr r1, [r3] "); // r1 = original aDest
1.1133 + asm("str ip, [r3] "); // aDest = ip
1.1134 + asm("sub r0, r1, ip "); // return aDest - ip
1.1135 + __JUMP(,lr);
1.1136 +#endif //__KERNEL_MODE__
1.1137 +
1.1138 + asm("do_convert_hex: ");
1.1139 + asm("mov r1, r2, lsl #22 "); // aA bit 8 into r1 bit 30
1.1140 + asm("adds r1, r1, r1 "); // set V flag = aA bit 8
1.1141 + asm("and r2, r2, #0xff ");
1.1142 + asm("sub r2, r2, #0x40 ");
1.1143 + asm("1: ");
1.1144 + asm("and r1, r0, #15 "); // r1 = aVal & 15
1.1145 + asm("add r1, r1, #0x36 "); // r1 += '0'+6
1.1146 + asm("tst r1, #0x40 ");
1.1147 + asm("subeq r1, r1, #6 ");
1.1148 + asm("addne r1, r1, r2 ");
1.1149 + asm("movs r0, r0, lsr #4 "); // aVal>>=4, V unaffected
1.1150 + asm("strvsh r1, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1151 + asm("strvcb r1, [ip, #-1]! "); // else store 8 bits
1.1152 + asm("bne 1b "); // loop back if aVal still nonzero
1.1153 + asm("ldr r1, [r3] "); // r1 = original aDest
1.1154 + asm("str ip, [r3] "); // aDest = ip
1.1155 + asm("sub r0, r1, ip "); // return aDest - ip
1.1156 + __JUMP(,lr);
1.1157 +
1.1158 + asm("do_convert_dec: ");
1.1159 + asm("and r2, r2, #0x100 "); // mask all bits of aA except bit 8
1.1160 + asm("orr r3, r3, r2, lsr #8 "); // r3 bit 0 = aA bit 8
1.1161 + asm("1: ");
1.1162 + asm("sub r1, r0, #10 "); // divide aVal by 10, r0=quotient, r1=remainder
1.1163 + asm("sub r0, r0, r0, lsr #2 ");
1.1164 + asm("add r0, r0, r0, lsr #4 ");
1.1165 + asm("add r0, r0, r0, lsr #8 ");
1.1166 + asm("add r0, r0, r0, lsr #16 ");
1.1167 + asm("mov r0, r0, lsr #3 ");
1.1168 + asm("add r2, r0, r0, lsl #2 ");
1.1169 + asm("subs r1, r1, r2, lsl #1 ");
1.1170 + asm("addpl r0, r0, #1 ");
1.1171 + asm("addmi r1, r1, #10 ");
1.1172 + asm("add r1, r1, #0x30 "); // add '0' to remainder
1.1173 + asm("tst r3, #1 "); // test aA bit 8
1.1174 + asm("strneh r1, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1175 + asm("streqb r1, [ip, #-1]! "); // else store 8 bits
1.1176 + asm("teq r0, #0 ");
1.1177 + asm("bne 1b "); // loop back if aVal still nonzero
1.1178 + asm("bic r3, r3, #1 ");
1.1179 + asm("ldr r1, [r3] "); // r1 = original aDest
1.1180 + asm("str ip, [r3] "); // aDest = ip
1.1181 + asm("sub r0, r1, ip "); // return aDest - ip
1.1182 + __JUMP(,lr);
1.1183 + }
1.1184 +
1.1185 +__NAKED__ GLDEF_C TInt __DoConvertNum(TUint64 /*aVal*/, TRadix /*aRadix*/, TUint /*aA*/, TUint8*& /*aDest*/)
1.1186 + {
1.1187 + asm("ldr ip, [sp] "); // ip = &aDest
1.1188 + asm("cmp r2, #16 ");
1.1189 + asm("beq do_convert_hex64 ");
1.1190 + asm("cmp r2, #10 ");
1.1191 + asm("beq do_convert_dec64 ");
1.1192 +#ifdef __KERNEL_MODE__
1.1193 + asm("mov r0, #%a0" : : "i" ((TInt)EInvalidRadix));
1.1194 + asm("b " CSM_Z5Panic9TCdtPanic);
1.1195 +#else // !__KERNEL_MODE__
1.1196 + asm("cmp r2, #2 ");
1.1197 + asm("beq do_convert_bin64 ");
1.1198 + asm("cmp r2, #8 ");
1.1199 + asm("beq do_convert_oct64 ");
1.1200 + asm("stmfd sp!, {r4-r8,lr} ");
1.1201 + asm("ldr r4, [ip] "); // r4 = aDest
1.1202 + asm("mov r5, r2 "); // save radix
1.1203 + asm("and r6, r3, #0xff "); // r6 = aA & 0xff
1.1204 + asm("sub r6, r6, #10 "); // save a - 10
1.1205 + asm("mov r7, ip "); // save &aDest
1.1206 + asm("mov r8, r3"); // save aA
1.1207 + asm("teq r1, #0 "); // aVal > 0xffffffffu
1.1208 + asm("beq 2f ");
1.1209 + asm("1: ");
1.1210 + asm("mov r3, #0 ");
1.1211 + asm("mov r2, r5 "); // r3:r2 = radix
1.1212 +#ifndef __EABI__
1.1213 + asm("stmfd sp!, {r4-r6} "); // push the registers that are scratched by UDiv01
1.1214 + asm(".extern UDiv01 ");
1.1215 + asm("bl UDiv01 "); // do division, quotient->r5:r4, rem->r6:r3
1.1216 + asm("mov r0, r4"); // move to make regs same as EABI function
1.1217 + asm("mov r1, r5");
1.1218 + asm("mov r2, r3");
1.1219 + asm("mov r3, r6");
1.1220 + asm("ldmfd sp!, {r4-r6} "); // pop the registers that are scratched by UDiv01
1.1221 +#else //__EABI__
1.1222 + asm(".extern __aeabi_uldivmod ");
1.1223 + asm("bl __aeabi_uldivmod "); // do division, quotient->r1:r0, rem->r3:r2
1.1224 +#endif //__EABI__
1.1225 + asm("cmp r2, #9 ");
1.1226 + asm("addhi r2, r2, r6 "); // r2 = (r2>9) ? r2+aA-10 : r2+'0'
1.1227 + asm("addls r2, r2, #0x30 ");
1.1228 + asm("tst r8, #0x100 ");
1.1229 + asm("strneh r2, [r4, #-2]! "); // *--r4 = (TUint16)r2
1.1230 + asm("streqb r2, [r4, #-1]! "); // *--r4 = (TUint8)r2
1.1231 + asm("teq r1, #0 "); // new aVal > 0xffffffffu
1.1232 + asm("bne 1b ");
1.1233 + asm("2: ");
1.1234 + asm("mov r2, r8 "); // r2 = aA
1.1235 + asm("ldr r1, [r7] "); // r1 = aDest
1.1236 + asm("mov r3, r7 "); // r3 = &aDest
1.1237 + asm("sub r6, r1, r4 "); // r6 = aDest - r4
1.1238 + asm("mov r1, r5 "); // r1 = radix
1.1239 + asm("str r4, [r3] "); // aDest = r4
1.1240 + asm("mov ip, r4 "); // ip = aDest
1.1241 + asm("bl do_convert_any ");
1.1242 + asm("add r0, r0, r6 "); // r0 += r6
1.1243 + __POPRET("r4-r8,");
1.1244 +
1.1245 + asm("do_convert_bin64: ");
1.1246 + asm("mov r2, ip "); // r2 = &aDest
1.1247 + asm("ldr ip, [ip] "); // ip = aDest
1.1248 + asm("mov r3, r3, lsl #22 "); // aA bit 8 into bit 30
1.1249 + asm("adds r3, r3, r3 "); // set V flag = aA bit 8
1.1250 + asm("teq r1, #0 "); // if (aVal <= 0xffffffffu)
1.1251 + asm("moveq r1, ip "); // r1 = orig. aDest in second half
1.1252 + asm("beq 2f "); // branch to second half of the loop
1.1253 + asm("1: ");
1.1254 + asm("movs r0, r0, lsr #1 "); // aVal >>= 1, bit 0 into carry, V unaffected
1.1255 + asm("mov r3, #0x30 "); // r3 = '0'
1.1256 + asm("adc r3, r3, #0 "); // add in carry
1.1257 + asm("strvsh r3, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1258 + asm("strvcb r3, [ip, #-1]! "); // else store 8 bits
1.1259 + asm("bne 1b "); // loop back if (aVal & 0xffffffffu) still nonzero
1.1260 + asm("ldr r0, [r2] "); // r0 = original aDest
1.1261 + asm("subvc r0, r0, #32 "); // r0 = end of buffer for first word (8-bit descriptor)
1.1262 + asm("subvs r0, r0, #64 "); // r0 = end of buffer for first word (16-bit descriptor)
1.1263 + asm("teq ip, r0 "); // don't pad if we have already emitted 32 bits
1.1264 + asm("beq finish_bin_zero_pad ");
1.1265 + asm("bin_zero_pad: ");
1.1266 + asm("mov r3, #0x30 "); // r3 = '0'
1.1267 + asm("bin_zero_pad_loop: ");
1.1268 + asm("strvsh r3, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1269 + asm("strvcb r3, [ip, #-1]! "); // else store 8 bits
1.1270 + asm("teq ip, r0 ");
1.1271 + asm("bne bin_zero_pad_loop "); // loop back if padding not complete
1.1272 + asm("finish_bin_zero_pad: ");
1.1273 + asm("addvc r0, r0, #32 "); // r0 = original aDest
1.1274 + asm("addvs r0, r0, #64 "); // r0 = original aDest
1.1275 + asm("mov r3, r1 ");
1.1276 + asm("mov r1, r0 ");
1.1277 + asm("mov r0, r3 "); // r1 = orig aDest, r0 = aVal >> 32
1.1278 + asm("2: ");
1.1279 + asm("movs r0, r0, lsr #1 "); // aVal >>= 1, bit 0 into carry, V unaffected
1.1280 + asm("mov r3, #0x30 "); // r3 = '0'
1.1281 + asm("adc r3, r3, #0 "); // add in carry
1.1282 + asm("strvsh r3, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1283 + asm("strvcb r3, [ip, #-1]! "); // else store 8 bits
1.1284 + asm("bne 2b "); // loop back if aVal still nonzero
1.1285 + asm("str ip, [r2] "); // aDest = ip
1.1286 + asm("sub r0, r1, ip "); // return aDest - ip
1.1287 + __JUMP(,lr);
1.1288 +
1.1289 + asm("do_convert_oct64: "); // Convert as 31 + 33 bits when > 32 bits
1.1290 + asm("mov r2, ip "); // r2 = &aDest
1.1291 + asm("ldr ip, [ip] "); // ip = aDest
1.1292 + asm("mov r3, r3, lsl #22 "); // aA bit 8 into bit 30
1.1293 + asm("adds r3, r3, r3 "); // set V flag = aA bit 8
1.1294 + asm("teq r1, #0 "); // if (aVal <= 0xffffffffu)
1.1295 + asm("moveq r1, ip "); // r1 = orig. aDest in second half
1.1296 + asm("beq 3f "); // branch to second half of the loop
1.1297 + asm("and r3, r0, #7 "); // r3 = aVal & 7
1.1298 + asm("mov r0, r0, lsr #3 "); // aVal>>=3, set Z accordingly, V unaffected
1.1299 + asm("orr r0, r0, r1, lsl #29 "); // note we now have the bottom 33 bits in r0:r3[2:0]
1.1300 + asm("ands r0, r0, #0x3fffffff "); // and the top 31 bits in r1
1.1301 + asm("mov r1, r1, lsr #1 ");
1.1302 + asm("add r3, r3, #0x30 "); // r3 += '0'
1.1303 + asm("strvsh r3, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1304 + asm("strvcb r3, [ip, #-1]! "); // else store 8 bits
1.1305 + asm("beq 2f ");
1.1306 + asm("1: ");
1.1307 + asm("and r3, r0, #7 "); // r3 = aVal & 7
1.1308 + asm("movs r0, r0, lsr #3 "); // aVal>>=3, set Z accordingly, V unaffected
1.1309 + asm("add r3, r3, #0x30 "); // r3 += '0'
1.1310 + asm("strvsh r3, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1311 + asm("strvcb r3, [ip, #-1]! "); // else store 8 bits
1.1312 + asm("bne 1b "); // loop back if (aVal & 0xffffffff) still nonzero
1.1313 + asm("2: ");
1.1314 + asm("ldr r0, [r2] "); // r0 = original aDest
1.1315 + asm("subvc r0, r0, #11 "); // r0 = end of buffer for first word (8-bit descriptor)
1.1316 + asm("subvs r0, r0, #22 "); // r0 = end of buffer for first word (16-bit descriptor)
1.1317 + asm("teq ip, r0 "); // don't pad if we have already emitted 32 bits
1.1318 + asm("beq finish_oct_zero_pad ");
1.1319 + asm("oct_zero_pad: ");
1.1320 + asm("mov r3, #0x30 "); // r3 = '0'
1.1321 + asm("oct_zero_pad_loop: ");
1.1322 + asm("strvsh r3, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1323 + asm("strvcb r3, [ip, #-1]! "); // else store 8 bits
1.1324 + asm("teq ip, r0 ");
1.1325 + asm("bne oct_zero_pad_loop "); // loop back if padding not complete
1.1326 + asm("finish_oct_zero_pad: ");
1.1327 + asm("addvc r0, r0, #11 "); // r0 = original aDest
1.1328 + asm("addvs r0, r0, #22 "); // r0 = original aDest
1.1329 + asm("mov r3, r0 ");
1.1330 + asm("mov r0, r1 ");
1.1331 + asm("mov r1, r3 "); // r1 = orig aDest, r0 = aVal >> 32
1.1332 + asm("3: ");
1.1333 + asm("and r3, r0, #7 "); // r3 = aVal & 7
1.1334 + asm("movs r0, r0, lsr #3 "); // aVal>>=3, set Z accordingly, V unaffected
1.1335 + asm("add r3, r3, #0x30 "); // r3 += '0'
1.1336 + asm("strvsh r3, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1337 + asm("strvcb r3, [ip, #-1]! "); // else store 8 bits
1.1338 + asm("bne 3b "); // loop back if aVal still nonzero
1.1339 + asm("str ip, [r2] "); // aDest = ip
1.1340 + asm("sub r0, r1, ip "); // return aDest - ip
1.1341 + __JUMP(,lr);
1.1342 +
1.1343 +#endif //__KERNEL_MODE__
1.1344 +
1.1345 + asm("do_convert_hex64: ");
1.1346 + asm("ldr ip, [ip] "); // ip = aDest
1.1347 + asm("mov r2, r3, lsl #22 "); // aA bit 8 into r2 bit 30
1.1348 + asm("adds r2, r2, r2 "); // set V flag = aA bit 8
1.1349 + asm("and r3, r3, #0xff "); // aA = aA & 0xff
1.1350 + asm("teq r1, #0 "); // if (aVal <= 0xffffffffu)
1.1351 + asm("sub r3, r3, #0x40 "); // bias by ('0' + 16) either way => r3 = aA - ('0' + 16)
1.1352 + asm("moveq r1, ip "); // r1 = orig. aDest in second half
1.1353 + asm("beq 2f "); // branch to second half of the loop
1.1354 + asm("1: ");
1.1355 + asm("and r2, r0, #0xf "); // r2 = aVal & 0xf
1.1356 + asm("add r2, r2, #0x36 "); // r2 += ('0' + 6)
1.1357 + asm("tst r2, #0x40 "); // if ((aVal & 0xf) > 9)
1.1358 + asm("addne r2, r2, r3 "); // r2 = (aVal & 0xf) + (aA - 10)
1.1359 + asm("subeq r2, r2, #6 "); // r2 = (aVal & 0xf) + '0'
1.1360 + asm("movs r0, r0, lsr #4 "); // aVal>>=4, V unaffected
1.1361 + asm("strvsh r2, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1362 + asm("strvcb r2, [ip, #-1]! "); // else store 8 bits
1.1363 + asm("bne 1b "); // loop back if (aVal & 0xffffffffu) still nonzero
1.1364 + asm("ldr r0, [sp] "); // r0 = &aDest
1.1365 + asm("ldr r2, [r0] "); // r2 = original aDest
1.1366 + asm("subvc r0, r2, #8 "); // r0 = end of buffer for first word (8-bit descriptor)
1.1367 + asm("subvs r0, r2, #16 "); // r0 = end of buffer for first word (16-bit descriptor)
1.1368 + asm("teq ip, r0 "); // don't pad if we have already emitted 32 bits
1.1369 + asm("beq finish_hex_zero_pad ");
1.1370 + asm("hex_zero_pad: ");
1.1371 + asm("mov r2, #0x30 "); // r3 = '0'
1.1372 + asm("hex_zero_pad_loop: ");
1.1373 + asm("strvsh r2, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1374 + asm("strvcb r2, [ip, #-1]! "); // else store 8 bits
1.1375 + asm("teq ip, r0 ");
1.1376 + asm("bne hex_zero_pad_loop "); // loop back if padding not complete
1.1377 + asm("finish_hex_zero_pad: ");
1.1378 + asm("addvc r0, r0, #8 "); // r0 = original aDest
1.1379 + asm("addvs r0, r0, #16 "); // r0 = original aDest
1.1380 + asm("mov r2, r0 ");
1.1381 + asm("mov r0, r1 ");
1.1382 + asm("mov r1, r2 "); // r1 = orig aDest, r0 = aVal >> 32
1.1383 + asm("2: ");
1.1384 + asm("and r2, r0, #0xf "); // r2 = aVal & 0xf
1.1385 + asm("add r2, r2, #0x36 "); // r2 += '0'+6
1.1386 + asm("tst r2, #0x40 ");
1.1387 + asm("subeq r2, r2, #6 "); // r2 = (aVal & 0xf) + '0'
1.1388 + asm("addne r2, r2, r3 "); // r2 = (aVal & 0xf) + (aA - 10)
1.1389 + asm("movs r0, r0, lsr #4 "); // aVal>>=4, V unaffected
1.1390 + asm("strvsh r2, [ip, #-2]! "); // if aA bit 8 set, store 16 bits
1.1391 + asm("strvcb r2, [ip, #-1]! "); // else store 8 bits
1.1392 + asm("bne 2b "); // loop back if aVal still nonzero
1.1393 + asm("ldr r2, [sp] "); // r2 = &aDest
1.1394 + asm("sub r0, r1, ip "); // return aDest - ip
1.1395 + asm("str ip, [r2] "); // aDest = ip
1.1396 + __JUMP(,lr);
1.1397 +
1.1398 +#ifndef __FIXED_POINT_64BIT_DIV10__
1.1399 +
1.1400 + asm("do_convert_dec64: "); // As generic case, except can save one reg as radix known
1.1401 + asm("stmfd sp!, {r4-r6,lr} ");
1.1402 + asm("ldr r4, [ip] "); // r4 = aDest
1.1403 + asm("mov r5, ip "); // save &aDest
1.1404 + asm("mov r6, r3"); // save aA
1.1405 + asm("teq r1, #0 "); // aVal > 0xffffffffu
1.1406 + asm("beq 2f ");
1.1407 + asm("1: ");
1.1408 + asm("mov r3, #0 ");
1.1409 + asm("mov r2, #10 "); // r3:r2 = radix
1.1410 +#ifndef __EABI__
1.1411 + asm("stmfd sp!, {r4-r6} "); // push the registers that are scratched by UDiv01
1.1412 + asm(".extern UDiv01 ");
1.1413 + asm("bl UDiv01 "); // do division, quotient->r5:r4, rem->r6:r3
1.1414 + asm("mov r0, r4"); // move to make regs same as EABI function
1.1415 + asm("mov r1, r5");
1.1416 + asm("mov r2, r3");
1.1417 + asm("mov r3, r6");
1.1418 + asm("ldmfd sp!, {r4-r6} "); // pop the registers that are scratched by UDiv01
1.1419 +#else //__EABI__
1.1420 + asm(".extern __aeabi_uldivmod ");
1.1421 + asm("bl __aeabi_uldivmod "); // do division, quotient->r1:r0, rem->r3:r2
1.1422 +#endif //__EABI__
1.1423 + asm("add r2, r2, #0x30 "); // add '0' to remainder
1.1424 + asm("tst r6, #0x100 ");
1.1425 + asm("strneh r2, [r4, #-2]! "); // *--r4 = (TUint16)r2
1.1426 + asm("streqb r2, [r4, #-1]! "); // *--r4 = (TUint8)r2
1.1427 + asm("teq r1, #0 "); // new aVal > 0xffffffffu
1.1428 + asm("bne 1b ");
1.1429 + asm("2: ");
1.1430 + asm("mov r2, r6 "); // r2 = aA
1.1431 + asm("ldr r1, [r5] "); // r1 = original aDest
1.1432 + asm("mov r3, r5 "); // r3 = &aDest
1.1433 + asm("sub r6, r1, r4 "); // r6 = original aDest - r4
1.1434 + asm("mov r1, #10 "); // r1 = radix
1.1435 + asm("str r4, [r3] "); // aDest = r4
1.1436 + asm("mov ip, r4 "); // ip = aDest
1.1437 + asm("bl do_convert_dec ");
1.1438 + asm("add r0, r0, r6 "); // r0 += r6
1.1439 + __POPRET("r4-r6,");
1.1440 +
1.1441 +#else //__FIXED_POINT_64BIT_DIV10__
1.1442 +
1.1443 + asm("do_convert_dec64: "); // Be extra cunning by doing fixed-point arithmetic using only shifts, adds and subtracts
1.1444 + asm("stmfd sp!, {r4-r7,lr} "); // - avoids costs of potentially inefficient calls to __aeabi_uldivmod
1.1445 + asm("mov r4, r3 "); // r4 = aA
1.1446 + asm("ldr r5, [ip] "); // r5 = aDest
1.1447 + asm("teq r1, #0 "); // aVal > 0xffffffffu
1.1448 + asm("beq 2f ");
1.1449 + asm("1: ");
1.1450 + asm("subs r2, r0, #10 "); // divide aVal by 10, r1:r0=quotient, r3:r2=remainder
1.1451 + asm("sbc r3, r1, #0 ");
1.1452 + asm("mov r6, r0, lsr #2 "); // NB: 0.8 rounded to 64 bits is:
1.1453 + asm("orr r6, r6, r1, lsl #30 "); // 0.11001100110011001100110011001100110011001100110011001100110011
1.1454 + asm("subs r0, r0, r6 ");
1.1455 + asm("sbc r1, r1, r1, lsr #2 "); // quotient -= quotient >> 2 (0.11)
1.1456 + asm("mov r6, r0, lsr #4 ");
1.1457 + asm("orr r6, r6, r1, lsl #28 ");
1.1458 + asm("adds r0, r0, r6 ");
1.1459 + asm("adc r1, r1, r1, lsr #4 "); // quotient += quotient >> 4 (0.110011)
1.1460 + asm("mov r6, r0, lsr #8 ");
1.1461 + asm("orr r6, r6, r1, lsl #24 ");
1.1462 + asm("adds r0, r0, r6 ");
1.1463 + asm("adc r1, r1, r1, lsr #8 "); // quotient += quotient >> 8 (0.11001100110011)
1.1464 + asm("mov r6, r0, lsr #16 ");
1.1465 + asm("orr r6, r6, r1, lsl #16 ");
1.1466 + asm("adds r0, r0, r6 ");
1.1467 + asm("adc r1, r1, r1, lsr #16 "); // quotient += quotient >> 16 (0.110011001100110011001100110011)
1.1468 + asm("adds r0, r0, r1 ");
1.1469 + asm("adc r1, r1, #0 "); // quotient += quotient >> 32 (0.11001100110011001100110011001100110011001100110011001100110011)
1.1470 + asm("mov r0, r0, lsr #3 ");
1.1471 + asm("orr r0, r0, r1, lsl #29 ");
1.1472 + asm("mov r1, r1, lsr #3 "); // quotient >>= 3 0.1 == (0.00011001100110011001100110011001100110011001100110011001100110011)
1.1473 + asm("mov r7, r1, lsl #2 "); // use r7:r6 as a temp
1.1474 + asm("orr r7, r7, r0, lsr #30 ");
1.1475 + asm("mov r6, r0, lsl #2 "); // r7:r6 = quotient << 2 == 4 * |aVal/10|
1.1476 + asm("adds r6, r6, r0 ");
1.1477 + asm("adc r7, r7, r1 "); // r7:r6 += quotient == 5 * |aVal/10|
1.1478 + asm("mov r7, r7, lsl #1 ");
1.1479 + asm("orr r7, r7, r6, lsr #31 ");
1.1480 + asm("mov r6, r6, lsl #1 "); // r7:r6 <<= 1 == 10 * |aVal/10|
1.1481 + asm("subs r2, r2, r6 ");
1.1482 + asm("sbcs r3, r3, r7 "); // r3:r2 = aVal - (10 * |aVal/10|) == remainder
1.1483 + asm("bpl fix_quotient ");
1.1484 + asm("adds r2, r2, #10 ");
1.1485 + asm("adc r3, r3, #0 "); // fix remainder
1.1486 + asm("b fix_end ");
1.1487 + asm("fix_quotient: ");
1.1488 + asm("adds r0, r0, #1 ");
1.1489 + asm("adc r1, r1, #0 "); // increment quotient
1.1490 + asm("fix_end: ");
1.1491 + asm("add r2, r2, #0x30 "); // add '0' to remainder
1.1492 + asm("tst r4, #0x100 "); // test aA bit 8
1.1493 + asm("strneh r2, [r5, #-2]! "); // if aA bit 8 set, store 16 bits
1.1494 + asm("streqb r2, [r5, #-1]! "); // else store 8 bits
1.1495 + asm("teq r1, #0 ");
1.1496 + asm("bne 1b "); // loop back if new aVal > 0xffffffffu
1.1497 + asm("2: ");
1.1498 + asm("mov r2, r4 "); // r2 = aA
1.1499 + asm("ldr r1, [ip] "); // r1 = original aDest
1.1500 + asm("mov r3, ip "); // r3 = &aDest
1.1501 + asm("sub r6, r1, r5 "); // r6 = original aDest - r5
1.1502 + asm("str r5, [r3] "); // aDest = r5
1.1503 + asm("mov r1, #10 "); // r1 = radix
1.1504 + asm("mov ip, r5 "); // ip = aDest
1.1505 + asm("bl do_convert_dec ");
1.1506 + asm("add r0, r0, r6 "); // r0 += r6
1.1507 + __POPRET("r4-r7,");
1.1508 +
1.1509 +#endif //__FIXED_POINT_64BIT_DIV10__
1.1510 +
1.1511 + }
1.1512 +
1.1513 +#endif //__DES_MACHINE_CODED__