// DECNUM3      Convert integer to ASCII

// This program converts a positive number from X3
// into a string of ASCII-encoded decimal digits at A3
// using the BOOTH function for its divide loop
        LEN     = 20              // Allowance for 20 digits
        DOT8    = 0xcccccccccccccccd  // 0.8 (approx.)
        .global booth             // External reference
        .data                     // Declare storage
        .align  8                 // Desired alignment
X3:     data8   0x123456789       // Number to convert
A3:     .skip   80                // ASCII output area
STACK:  .skip   LEN               // User-defined stack
        .text                     // Section for code
        .align  32                // Desired alignment
        .global main              // These three lines
        .proc   main              //  mark the mandatory
main:                             //   'main' program entry
        .prologue 12,r32          // Mask for rp, ar.pfs only
        alloc   loc1 = ar.pfs,0,6,2,0 // 6 locals, 2 outs
        .save   rp,loc0           // Must save return address
        mov     loc0 = b0         //  to our caller
        .body                     // Now we really begin...
first:  add     loc2 = @gprel(STACK),gp  // loc2 -> stack
        movl    loc3 = DOT8       // 0.8 reciprocal factor
        mov     loc5 = gp         // Save gp
new:    add     r15 = @gprel(X3),gp;;    // r15 -> input
        ld8     r9 = [r15]        // Get number to convert
        st1     [loc2] = r0,1;;   // Push 0 as a flag
again:  mov     loc4 = r9         // Save previous quotient
        mov     out0 = r9         // It is the multiplicand
        mov     out1 = loc3       // 0.8 is the multiplier
        br.call.sptk.many b0=booth  // r9,r8 = out0 * out1
        mov     gp = loc5         // Restore gp
nosign: add     r9 = r9,loc4;;    // Add X to L
        shr.u   r9 = r9,3;;       // r9 = quotient = loc4/10
        shladd  r3 = r9,2,r9;;    // r3 = 5*quotient
        add     r3 = r3,r3;;      // r3 = 10*quotient now
        sub     r3 = loc4,r3;;    // r3 = remainder now
        or      r3 = 0x30,r3;;    // Make into ASCII char
        st1     [loc2] = r3,1     // Store the character
        cmp.ne  p6,p0 = r9,r0     // If quotient not zero,
   (p6) br.cond.sptk.few again;;  //  repeat the cycle
        add     loc2 = -2,loc2    // Skip latest char
        add     r16 = @gprel(A3),gp;;    // r16 -> output
move:   st1     [r16] = r3,1      // Move one character
        ld1     r3 = [loc2],-1;;  // Get another character
        cmp.ne  p6,p0 = r3,r0     // If it is not 0 flag
   (p6) br.cond.sptk.few move     //  then move it to A3 area
        st1     [r16] = r0        // Make A3 into stringz
        add     loc2 = 1,loc2     // Fix stack pointer
done:   mov     r8 = r0           // Signal all is normal
        mov     b0 = loc0         // Restore return address
        mov     ar.pfs = loc1     // Restore caller's ar.pfs
        br.ret.sptk.many b0;;     // Back to command line
        .endp   main              // Mark end of procedure