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