string-transform/transform.s
2025-04-20 08:56:58 +12:00

99 lines
2 KiB
ArmAsm

.globl transform
.extern strlen
.extern malloc
# this stuff didnt really need to be a macro but whatever
.macro begin_func
# regs reg size return address 16 byte align padding
addi sp, sp, -112 # 12 * 8 + 8 + 8
sd ra, 104(sp)
sd s0, 96(sp)
sd s1, 88(sp)
sd s2, 80(sp)
sd s3, 72(sp)
sd s4, 64(sp)
sd s5, 56(sp)
sd s6, 48(sp)
sd s7, 40(sp)
sd s8, 32(sp)
sd s9, 24(sp)
sd s10, 16(sp)
sd s11, 8(sp)
.endm
.macro end_func
ld ra, 104(sp)
ld s0, 96(sp)
ld s1, 88(sp)
ld s2, 80(sp)
ld s3, 72(sp)
ld s4, 64(sp)
ld s5, 56(sp)
ld s6, 48(sp)
ld s7, 40(sp)
ld s8, 32(sp)
ld s9, 24(sp)
ld s10, 16(sp)
ld s11, 8(sp)
addi sp, sp, 112
ret
.endm
.section .text
transform:
begin_func
# s0 = input ip pointer
# s1 = input length
# s2 = buffer length
# s3 = buffer pointer
mv s0, a0
call strlen
mv s1, a0
li t0, 3
mul s2, s1, t0 # multiply input length by 3 to get maximum possible output length
mv a0, s2
addi a0, a0, 1 # add space for null terminator
call malloc
mv s3, a0
beq s3, x0, .exit # if allocation failed exit the function
mv t0, x0 # i
mv t1, x0 # out_i
.loop_start:
bge t0, s1, .loop_end # if i == len finish looping
add t2, s0, t0 # t2 = ip + i
lb t3, 0(t2) # t3 has the char
li t5, '.'
bne t3, t5, .store_char # if the period isnt present skip adding the [
add t4, s3, t1 # t4 = buf + out_i
li t6, '['
sb t6, 0(t4) # *t4 = '['
addi t1, t1, 1
.store_char:
add t4, s3, t1 # t4 = buf + out_i
sb t3, 0(t4) # *t4 = t3 (the current char)
addi t0, t0, 1
addi t1, t1, 1
bne t3, t5, .loop_start # if the period isnt present go back to start of loop
add t4, s3, t1 # t4 = buf + out_i
li t6, ']'
sb t6, 0(t4) # *t4 = ']'
addi t1, t1, 1
j .loop_start
.loop_end:
addi t4, t4, 1
sb x0, 0(t4) # add null terminator
.exit:
mv a0, s3 # put buffer into return register
end_func