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