99 lines
2 KiB
ArmAsm
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
|