aboutsummaryrefslogtreecommitdiff
path: root/src/lib/tub2tsv.s
blob: 558c51e43a4601fd8a40c8a371ee4fec988a0b44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# --------------------------------------------
# FUNCTION: tub2tsv
# PURPOSE : take a buffer of coordinates
#           and print each coordinate on a line
# INPUTS  : rdi = pointer to buffer,
#           rsi = number of coordinates
# OUTPUTS : rax = address to string of tab seperated values
#           rdx = number of bytes
# CLOBBERS: 
# --------------------------------------------
.section .text
.globl tub2tsv
.type tub2tsv, @function
tub2tsv:
    # save callee-saved registers
    pushq %r12
    pushq %r13
    pushq %r14
    pushq %r15
    pushq %rbx

    movq %rdi, %r12                 # r12 = address to array of coordinates
    movq %rsi, %r13                 # r13 = count of coordinates

    # allocate memory based on number of coordinates and max integer size
    # maybe allocate in chunks might be better, as to waste less memory
    movq %rsi, %rdi
    imulq $42, %rdi                 # 20 bytes for each coordindate + tab
    incq %rdi                       # +1 byte for null terminator
    call allocate
    movq %rax, %r14                 # r14 = output buffer start
    movq %rax, %r15                 # r15 = current write pos

    xorq %rbx, %rbx                 # loop counter

.tub2tsv_loop:
    cmpq %r13, %rbx                 # if loop counter >= count of coordinates
    jge .tub2tsv_exit               # done
    
    # get addrss to current tuple
    movq (%r12, %rbx, 8), %rdi      # rdi = array[loop counter]
    pushq %rdi                      # save pointer to current tuple

    # convert first integer to ASCII
    movq (%rdi), %rdi               # rdi = first int
    movq %r15, %rsi                 # rsi = current write pos
    call int2str                    # rax = string start, rdx = length
    addq %rdx, %r15                 # advance write pos with num bytes written 
    
    # write tab
    movb $'\t', (%r15)
    incq %r15 

    # convert second integer to ASCII
    popq %rdi                       # restore pointer to tuple
    movq 8(%rdi), %rdi              # rdi = second int
    movq %r15, %rsi                 # rsi = current write pos
    call int2str                    # rax = string start, rdx = length
    addq %rdx, %r15                 # advance write pos with num bytes written

    # write newline
    movb $'\n', (%r15)
    incq %r15 

    incq %rbx
    jmp .tub2tsv_loop

.tub2tsv_exit:
    # add null terminator
    movb $0, (%r15)

    # move address to output register
    movq %r14, %rax

    # return length in rdx
    movq %r15, %rdx
    subq %r14, %rdx

    # restore callee-saved registers
    popq %rbx
    popq %r15
    popq %r14
    popq %r13
    popq %r12

    ret