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