Change armv4t integer to string conversion to use an unrolled loop
This implementation also writes the digits from left to right instead of right to left. Using this method we can write the string to the beginning of the buffer and still avoid reversing the string. It also has the benefit of being slightly slower than the previous implementation. The function's signature changed as well because there is no longer a reason to pass the buffer size or a pointer to output the start of the string.
This commit is contained in:
parent
bd1efb0bf9
commit
dbdf8b6e3c
@ -17,10 +17,11 @@ void mtl_hybridmove(void* dst, const void* src, size_t num8);
|
|||||||
|
|
||||||
uint32_t mtl_udiv10(uint32_t x);
|
uint32_t mtl_udiv10(uint32_t x);
|
||||||
uint32_t mtl_umod10(uint32_t x);
|
uint32_t mtl_umod10(uint32_t x);
|
||||||
uint32_t mtl_utostr(uint32_t x, char* buf, size_t buf_size, char** buf_out);
|
|
||||||
uint32_t mtl_utostrx(uint32_t x, char* buf, size_t buf_size, char** buf_out);
|
uint32_t mtl_utostr(uint32_t x, char* buf);
|
||||||
uint32_t mtl_itostr(uint32_t x, char* buf, size_t buf_size, char** buf_out);
|
uint32_t mtl_utostrx(uint32_t x, char* buf);
|
||||||
uint32_t mtl_itostrx(uint32_t x, char* buf, size_t buf_size, char** buf_out);
|
uint32_t mtl_itostr(int32_t x, char* buf);
|
||||||
|
uint32_t mtl_itostrx(int32_t x, char* buf);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
558
src/armv4t/to.s
558
src/armv4t/to.s
@ -2,244 +2,350 @@
|
|||||||
|
|
||||||
.include "mtl/armv4t/asm/math.s"
|
.include "mtl/armv4t/asm/math.s"
|
||||||
|
|
||||||
.section .rodata
|
|
||||||
|
|
||||||
.align 1
|
|
||||||
hex_digits_lo:
|
|
||||||
.string "0123456789abcdef"
|
|
||||||
hex_digits_up:
|
|
||||||
.string "0123456789ABCDEF"
|
|
||||||
|
|
||||||
.section .iwram, "ax", %progbits
|
.section .iwram, "ax", %progbits
|
||||||
.arm
|
.arm
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
/*
|
|
||||||
* Writes the ASCII representation of the given unsigned value X to the buffer,
|
|
||||||
* writes the beginning address of the string to an output ptr, and returns
|
|
||||||
* the number of characters written. The value is written in hexidecimal
|
|
||||||
* format.
|
|
||||||
*
|
|
||||||
* r0 = x
|
|
||||||
* r1 = buffer start
|
|
||||||
* r2 = buffer size
|
|
||||||
* r3 = string start out ptr
|
|
||||||
* ret= num of characters written
|
|
||||||
*/
|
|
||||||
.global mtl_utostrx
|
|
||||||
.type mtl_utostrx STT_FUNC
|
|
||||||
mtl_utostrx:
|
|
||||||
// Store variables
|
|
||||||
push {r4-r7}
|
|
||||||
// Move buffer to end
|
|
||||||
add r1, r2
|
|
||||||
sub r1, $1
|
|
||||||
// Add null terminator and decrement
|
|
||||||
mov r6, $0
|
|
||||||
str r6, [r1], $-1
|
|
||||||
// Load digit address
|
|
||||||
ldr r4, =hex_digits_lo
|
|
||||||
// Zero num of characters
|
|
||||||
mov r7, $0
|
|
||||||
.Ldecode_digitx:
|
|
||||||
// Increment number of characters
|
|
||||||
add r7, $1
|
|
||||||
// Get least significant octet
|
|
||||||
and r6, r0, 0xF
|
|
||||||
// Write the ascii digit to the string
|
|
||||||
ldrb r5, [r4, r6]
|
|
||||||
strb r5, [r1], $-1
|
|
||||||
// Shift to remove the least significant octet
|
|
||||||
lsrs r0, $4
|
|
||||||
// Repeat if there are more digits left
|
|
||||||
bne .Ldecode_digitx
|
|
||||||
// Move to the start of the string and account for "0x",
|
|
||||||
// currently one character before
|
|
||||||
sub r1, $1
|
|
||||||
//add r1, $1
|
|
||||||
// Write "0x" to the beginning of the string
|
|
||||||
mov r6, '0'
|
|
||||||
strb r6, [r1]
|
|
||||||
mov r6, 'x'
|
|
||||||
strb r6, [r1, $1]
|
|
||||||
// Write the start of the string to the pointer
|
|
||||||
str r1, [r3]
|
|
||||||
// Return the number of characters written, account for "0x"
|
|
||||||
add r0, r7, $2
|
|
||||||
// Restore variables
|
|
||||||
pop {r4-r7}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Writes the ASCII representation of the given unsigned value X to the buffer,
|
|
||||||
* writes the beginning address of the string to an output ptr, and returns
|
|
||||||
* the number of characters written. The value is written in decimal format.
|
|
||||||
*
|
|
||||||
* r0 = x
|
|
||||||
* r1 = buffer start
|
|
||||||
* r2 = buffer size
|
|
||||||
* r3 = string start out ptr
|
|
||||||
* ret= num of characters written
|
|
||||||
*/
|
|
||||||
.global mtl_utostr
|
|
||||||
.type mtl_utostr STT_FUNC
|
|
||||||
mtl_utostr:
|
|
||||||
// Store variables
|
|
||||||
push {r4-r7}
|
|
||||||
// Move buffer to end
|
|
||||||
add r1, r2
|
|
||||||
sub r1, $1
|
|
||||||
// Add null terminator and decrement
|
|
||||||
mov r6, $0
|
|
||||||
str r6, [r1], $-1
|
|
||||||
// Zero num of characters
|
|
||||||
mov r7, $0
|
|
||||||
.Ldecode_digit:
|
|
||||||
// Increment number of characters
|
|
||||||
add r7, $1
|
|
||||||
// Use % 10 to get the least significant digit
|
|
||||||
umod10 r6, r0, r12
|
|
||||||
// Write the ascii digit to the string
|
|
||||||
add r5, r6, '0'
|
|
||||||
strb r5, [r1], $-1
|
|
||||||
// Divide by 10 to remove the least significant digit
|
|
||||||
udiv10 r6, r0, r12
|
|
||||||
mov r0, r6
|
|
||||||
// Repeat if there are more digits left
|
|
||||||
bne .Ldecode_digit
|
|
||||||
// Move to the start of the string, currently one char before
|
|
||||||
add r1, $1
|
|
||||||
// Write the start of the string to the pointer
|
|
||||||
str r1, [r3]
|
|
||||||
// Return the number of characters written
|
|
||||||
mov r0, r7
|
|
||||||
// Restore variables
|
|
||||||
pop {r4-r7}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writes the ASCII representation of the given signed value X to the buffer,
|
* Writes the ASCII representation of the given signed value X to the buffer,
|
||||||
* writes the beginning address of the string to an output ptr, and returns
|
* returns the number of characters written. The value is written in decimal
|
||||||
* the number of characters written. The value is written in hexidecimal
|
* format and is null terminated. The string will always begin at the start of
|
||||||
* format.
|
* the buffer.
|
||||||
*
|
*
|
||||||
* r0 = x
|
* r0 = x
|
||||||
* r1 = buffer start
|
* r1 = buffer
|
||||||
* r2 = buffer size
|
|
||||||
* r3 = string start out ptr
|
|
||||||
* ret= num of characters written
|
|
||||||
*/
|
|
||||||
.global mtl_itostrx
|
|
||||||
.type mtl_itostrx STT_FUNC
|
|
||||||
mtl_itostrx:
|
|
||||||
// Store variables
|
|
||||||
push {r4-r8}
|
|
||||||
// r8 = 1 if negative, 0 if positive. Negate if negative
|
|
||||||
lsrs r8, r0, $31
|
|
||||||
mvnne r0, r0
|
|
||||||
addne r0, $1
|
|
||||||
// Move buffer to end
|
|
||||||
add r1, r2
|
|
||||||
sub r1, $1
|
|
||||||
// Add null terminator and decrement
|
|
||||||
mov r6, $0
|
|
||||||
str r6, [r1], $-1
|
|
||||||
// Load digit address
|
|
||||||
ldr r4, =hex_digits_lo
|
|
||||||
// Zero num of characters
|
|
||||||
mov r7, $0
|
|
||||||
.Lsdecode_digitx:
|
|
||||||
// Increment number of characters
|
|
||||||
add r7, $1
|
|
||||||
// Get least significant octet
|
|
||||||
and r6, r0, 0xF
|
|
||||||
// Write the ascii digit to the string
|
|
||||||
ldrb r5, [r4, r6]
|
|
||||||
strb r5, [r1], $-1
|
|
||||||
// Shift to remove the least significant octet
|
|
||||||
lsrs r0, $4
|
|
||||||
// Repeat if there are more digits left
|
|
||||||
bne .Lsdecode_digitx
|
|
||||||
// Move to the start of the string and account for "0x",
|
|
||||||
// currently one character before
|
|
||||||
sub r1, $1
|
|
||||||
// Write "0x" to the beginning of the string
|
|
||||||
mov r6, '0'
|
|
||||||
strb r6, [r1]
|
|
||||||
mov r6, 'x'
|
|
||||||
strb r6, [r1, $1]
|
|
||||||
// Check if number is negative
|
|
||||||
cmp r8, $0
|
|
||||||
// Add the negative sign to the string and increase number of
|
|
||||||
// characters written if needed
|
|
||||||
subne r1, $1
|
|
||||||
movne r6, '-'
|
|
||||||
strbne r6, [r1]
|
|
||||||
addne r7, $1
|
|
||||||
// Write the start of the string to the pointer
|
|
||||||
str r1, [r3]
|
|
||||||
// Return the number of characters written, account for "0x"
|
|
||||||
add r0, r7, $2
|
|
||||||
// Restore variables
|
|
||||||
pop {r4-r8}
|
|
||||||
bx lr
|
|
||||||
/*
|
|
||||||
* Writes the ASCII representation of the given signed value X to the buffer,
|
|
||||||
* writes the beginning address of the string to an output ptr, and returns
|
|
||||||
* the number of characters written. The value is written in decimal format.
|
|
||||||
*
|
|
||||||
* r0 = x
|
|
||||||
* r1 = buffer start
|
|
||||||
* r2 = buffer size
|
|
||||||
* r3 = string start out ptr
|
|
||||||
* ret= num of characters written
|
* ret= num of characters written
|
||||||
*/
|
*/
|
||||||
.global mtl_itostr
|
.global mtl_itostr
|
||||||
.type mtl_itostr STT_FUNC
|
.type mtl_itostr STT_FUNC
|
||||||
mtl_itostr:
|
mtl_itostr:
|
||||||
// Store variables
|
// Branch immediately if the number is positive
|
||||||
push {r4-r8}
|
lsrs r12, r0, $31
|
||||||
// r8 = 1 if negative, 0 if positive. Negate if negative
|
beq mtl_utostr
|
||||||
lsrs r8, r0, $31
|
// Write the negative sign to the string
|
||||||
mvnne r0, r0
|
mvn r0, r0
|
||||||
addne r0, $1
|
add r0, $1
|
||||||
// Move buffer to end
|
// Get the absolute value of the number
|
||||||
add r1, r2
|
mov r12, '-'
|
||||||
sub r1, $1
|
strb r12, [r1], $1
|
||||||
// Add null terminator and decrement
|
// Write abs(x) to the string
|
||||||
mov r6, $0
|
push {fp, lr}
|
||||||
str r6, [r1], $-1
|
bl mtl_utostr
|
||||||
// Zero num of characters
|
pop {fp, lr}
|
||||||
mov r7, $0
|
// One more character was written to the string ('-')
|
||||||
.Lsdecode_digit:
|
add r0, $1
|
||||||
// Increment number of characters
|
bx lr
|
||||||
add r7, $1
|
|
||||||
// Use % 10 to get the least significant digit
|
/*
|
||||||
umod10 r6, r0, r12
|
* Writes the ASCII representation of the given signed value X to the buffer,
|
||||||
// Write the ascii digit to the string
|
* returns the number of characters written. The value is written in hexadecimal
|
||||||
add r5, r6, '0'
|
* format and is null terminated. The string will always begin at the start of
|
||||||
strb r5, [r1], $-1
|
* the buffer.
|
||||||
// Divide by 10 to remove the least significant digit
|
*
|
||||||
udiv10 r6, r0, r12
|
* r0 = x
|
||||||
mov r0, r6
|
* r1 = buffer
|
||||||
// Repeat if there are more digits left
|
* ret= num of characters written
|
||||||
bne .Lsdecode_digit
|
*/
|
||||||
// Check if number is negative
|
.global mtl_itostrx
|
||||||
cmp r8, $0
|
.type mtl_itostrx STT_FUNC
|
||||||
// Add the negative sign to the string and increase number of
|
mtl_itostrx:
|
||||||
// characters written if needed
|
// Branch immediately if the number is positive
|
||||||
movne r6, '-'
|
lsrs r12, r0, $31
|
||||||
strbne r6, [r1]
|
beq mtl_utostrx
|
||||||
addne r7, $1
|
// Write the negative sign to the string
|
||||||
// If the number was positive, currently positioned one char before str
|
mov r12, '-'
|
||||||
// If the number was negative, currently at the correct position
|
strb r12, [r1], $1
|
||||||
// Move one character forward if needed
|
// Get the absolute value of the number
|
||||||
addeq r1, $1
|
mvn r0, r0
|
||||||
// Write the start of the string to the pointer
|
add r0, $1
|
||||||
str r1, [r3]
|
// Write abs(x) to the string
|
||||||
// Return the number of characters written
|
push {fp, lr}
|
||||||
mov r0, r7
|
bl mtl_utostrx
|
||||||
// Restore variables
|
pop {fp, lr}
|
||||||
pop {r4-r8}
|
// One more character was written to the string ('-')
|
||||||
|
add r0, $1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Writes the ASCII representation of the given unsigned value X to the buffer,
|
||||||
|
* returns the number of characters written. The value is written in decimal
|
||||||
|
* format and is null terminated. The string will always begin at the start of
|
||||||
|
* the buffer.
|
||||||
|
*
|
||||||
|
* Instead of using a loop like the previous implementation, this implementation
|
||||||
|
* uses a manually unrolled loop. This implementation also writes the digits
|
||||||
|
* from left to right instead of right to left. Using this method we can write
|
||||||
|
* the string to the beginning of the buffer and still avoid reversing the string.
|
||||||
|
*
|
||||||
|
* r0 = x
|
||||||
|
* r1 = buffer
|
||||||
|
* ret= num of characters written
|
||||||
|
*/
|
||||||
|
.global mtl_utostr
|
||||||
|
.type mtl_utostr STT_FUNC
|
||||||
|
mtl_utostr:
|
||||||
|
// Store variables
|
||||||
|
push {r4-r6}
|
||||||
|
// Temporary used to calculate 10^P
|
||||||
|
mov r5, $10
|
||||||
|
// Minimum of 1 digit
|
||||||
|
mov r3, $1
|
||||||
|
// If less than 10, one digit, otherwise more
|
||||||
|
mov r4, $10
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_1
|
||||||
|
// Now 2 digits
|
||||||
|
add r3, $1
|
||||||
|
// If less than 100, two digits, otherwise more
|
||||||
|
mul r4, r5
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_2
|
||||||
|
// Repeat...
|
||||||
|
add r3, $1
|
||||||
|
mul r4, r5
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_3
|
||||||
|
add r3, $1
|
||||||
|
mul r4, r5
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_4
|
||||||
|
add r3, $1
|
||||||
|
mul r4, r5
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_5
|
||||||
|
add r3, $1
|
||||||
|
mul r4, r5
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_6
|
||||||
|
add r3, $1
|
||||||
|
mul r4, r5
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_7
|
||||||
|
add r3, $1
|
||||||
|
mul r4, r5
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_8
|
||||||
|
add r3, $1
|
||||||
|
mul r4, r5
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Ldigits_9
|
||||||
|
// 10 digits
|
||||||
|
add r3, $1
|
||||||
|
.Ldigits_10:
|
||||||
|
// Divide by 10^9 to get the most significant digit
|
||||||
|
udiv1000000000 r5, r0, r12
|
||||||
|
// Write the digit to the string
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
// Subtract the most significant digit
|
||||||
|
ldr r6, =1000000000
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_9:
|
||||||
|
// Repeat...
|
||||||
|
udiv100000000 r5, r0, r12
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
ldr r6, =100000000
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_8:
|
||||||
|
udiv10000000 r5, r0, r12
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
ldr r6, =10000000
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_7:
|
||||||
|
udiv1000000 r5, r0, r12
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
ldr r6, =1000000
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_6:
|
||||||
|
udiv100000 r5, r0, r12
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
ldr r6, =100000
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_5:
|
||||||
|
udiv10000 r5, r0, r12
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
ldr r6, =10000
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_4:
|
||||||
|
udiv1000 r5, r0, r12
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
mov r6, $1000
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_3:
|
||||||
|
udiv100 r5, r0, r12
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
mov r6, $100
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_2:
|
||||||
|
udiv10 r5, r0, r12
|
||||||
|
add r6, r5, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
mov r6, $10
|
||||||
|
mul r6, r5
|
||||||
|
sub r0, r6
|
||||||
|
.Ldigits_1:
|
||||||
|
add r6, r0, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
|
||||||
|
// Write the null terminator
|
||||||
|
mov r6, $0
|
||||||
|
strb r6, [r1]
|
||||||
|
// Return number of digits written
|
||||||
|
mov r0, r3
|
||||||
|
// Restore variables
|
||||||
|
pop {r4-r6}
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Writes the ASCII representation of the given unsigned value X to the buffer,
|
||||||
|
* returns the number of characters written. The value is written in hexadecimal
|
||||||
|
* format and is null terminated. The string will always begin at the start of
|
||||||
|
* the buffer.
|
||||||
|
*
|
||||||
|
* Instead of using a loop like the previous implementation, this implementation
|
||||||
|
* uses a manually unrolled loop. This implementation also writes the digits
|
||||||
|
* from left to right instead of right to left. Using this method we can write
|
||||||
|
* the string to the beginning of the buffer and still avoid reversing the string.
|
||||||
|
*
|
||||||
|
* r0 = x
|
||||||
|
* r1 = buffer
|
||||||
|
* ret= num of characters written
|
||||||
|
*/
|
||||||
|
.global mtl_utostrx
|
||||||
|
.type mtl_utostrx STT_FUNC
|
||||||
|
mtl_utostrx:
|
||||||
|
// Store variables
|
||||||
|
push {r4-r6}
|
||||||
|
// Write "0x" to the string
|
||||||
|
mov r6, '0'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
mov r6, 'x'
|
||||||
|
strb r6, [r1], $1
|
||||||
|
|
||||||
|
// Minimum of 3 characters (including "0x")
|
||||||
|
mov r3, $3
|
||||||
|
// If less than 0x10, one digit, otherwise more
|
||||||
|
mov r4, $0x10
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Lxdigits_1
|
||||||
|
// Now four characters
|
||||||
|
add r3, $1
|
||||||
|
// If less than 0x100, two digits, otherwise more
|
||||||
|
lsl r4, $4
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Lxdigits_2
|
||||||
|
// Repeat...
|
||||||
|
add r3, $1
|
||||||
|
lsl r4, $4
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Lxdigits_3
|
||||||
|
add r3, $1
|
||||||
|
lsl r4, $4
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Lxdigits_4
|
||||||
|
add r3, $1
|
||||||
|
lsl r4, $4
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Lxdigits_5
|
||||||
|
add r3, $1
|
||||||
|
lsl r4, $4
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Lxdigits_6
|
||||||
|
add r3, $1
|
||||||
|
lsl r4, $4
|
||||||
|
cmp r0, r4
|
||||||
|
blo .Lxdigits_7
|
||||||
|
// Eight digits
|
||||||
|
add r3, $1
|
||||||
|
.Lxdigits_8:
|
||||||
|
// Right shift to get the most significant digit
|
||||||
|
lsr r5, r0, $28
|
||||||
|
// Get digit character
|
||||||
|
add r6, r5, '0'
|
||||||
|
// If the digit > 9, change to a lowercase letter
|
||||||
|
cmp r6, '9'
|
||||||
|
addhi r6, $0x27
|
||||||
|
// Write the digit
|
||||||
|
strb r6, [r1], $1
|
||||||
|
// Subtract the digit
|
||||||
|
lsl r5, $28
|
||||||
|
sub r0, r5
|
||||||
|
.Lxdigits_7:
|
||||||
|
// Repeat...
|
||||||
|
lsr r5, r0, $24
|
||||||
|
add r6, r5, '0'
|
||||||
|
cmp r6, '9'
|
||||||
|
addhi r6, $0x27
|
||||||
|
strb r6, [r1], $1
|
||||||
|
lsl r5, $24
|
||||||
|
sub r0, r5
|
||||||
|
.Lxdigits_6:
|
||||||
|
lsr r5, r0, $20
|
||||||
|
add r6, r5, '0'
|
||||||
|
cmp r6, '9'
|
||||||
|
addhi r6, $0x27
|
||||||
|
strb r6, [r1], $1
|
||||||
|
lsl r5, $20
|
||||||
|
sub r0, r5
|
||||||
|
.Lxdigits_5:
|
||||||
|
lsr r5, r0, $16
|
||||||
|
add r6, r5, '0'
|
||||||
|
cmp r6, '9'
|
||||||
|
addhi r6, $0x27
|
||||||
|
strb r6, [r1], $1
|
||||||
|
lsl r5, $16
|
||||||
|
sub r0, r5
|
||||||
|
.Lxdigits_4:
|
||||||
|
lsr r5, r0, $12
|
||||||
|
add r6, r5, '0'
|
||||||
|
cmp r6, '9'
|
||||||
|
addhi r6, $0x27
|
||||||
|
strb r6, [r1], $1
|
||||||
|
lsl r5, $12
|
||||||
|
sub r0, r5
|
||||||
|
.Lxdigits_3:
|
||||||
|
lsr r5, r0, $8
|
||||||
|
add r6, r5, '0'
|
||||||
|
cmp r6, '9'
|
||||||
|
addhi r6, $0x27
|
||||||
|
strb r6, [r1], $1
|
||||||
|
lsl r5, $8
|
||||||
|
sub r0, r5
|
||||||
|
.Lxdigits_2:
|
||||||
|
lsr r5, r0, $4
|
||||||
|
add r6, r5, '0'
|
||||||
|
cmp r6, '9'
|
||||||
|
addhi r6, $0x27
|
||||||
|
strb r6, [r1], $1
|
||||||
|
lsl r5, $4
|
||||||
|
sub r0, r5
|
||||||
|
.Lxdigits_1:
|
||||||
|
add r6, r0, '0'
|
||||||
|
cmp r6, '9'
|
||||||
|
addhi r6, $0x27
|
||||||
|
strb r6, [r1], $1
|
||||||
|
|
||||||
|
// Write the null terminator
|
||||||
|
mov r6, $0
|
||||||
|
strb r6, [r1]
|
||||||
|
// Return the number of digits written
|
||||||
|
mov r0, r3
|
||||||
|
// Restore variables
|
||||||
|
pop {r4-r6}
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user