Add armv4t assembly optimized integer to string conversion functions
This commit is contained in:
parent
998e3adf4d
commit
0a84391c39
245
src/armv4t/to.s
Normal file
245
src/armv4t/to.s
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.include "mtl/armv4t/asm/math.s"
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
|
||||||
|
.align 1
|
||||||
|
hex_digits_lo:
|
||||||
|
.string "0123456789abcdef"
|
||||||
|
hex_digits_up:
|
||||||
|
.string "0123456789ABCDEF"
|
||||||
|
|
||||||
|
.section .iwram, "ax", %progbits
|
||||||
|
.arm
|
||||||
|
.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 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_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
|
||||||
|
*/
|
||||||
|
.global mtl_itostr
|
||||||
|
.type mtl_itostr STT_FUNC
|
||||||
|
mtl_itostr:
|
||||||
|
// 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
|
||||||
|
// Zero num of characters
|
||||||
|
mov r7, $0
|
||||||
|
.Lsdecode_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 .Lsdecode_digit
|
||||||
|
// Check if number is negative
|
||||||
|
cmp r8, $0
|
||||||
|
// Add the negative sign to the string and increase number of
|
||||||
|
// characters written if needed
|
||||||
|
movne r6, '-'
|
||||||
|
strbne r6, [r1]
|
||||||
|
addne r7, $1
|
||||||
|
// If the number was positive, currently positioned one char before str
|
||||||
|
// If the number was negative, currently at the correct position
|
||||||
|
// Move one character forward if needed
|
||||||
|
addeq 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-r8}
|
||||||
|
bx lr
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user