// DECNUM2      Convert integer to ASCII

// This program converts a positive number from X2
// into a string of ASCII-encoded decimal digits at A2
        W       = 64              // W = number width
        LEN     = 20              // Allowance for 20 digits
        DOT8    = 0xcccccccccccccccd  // 0.8 (approx.)
        .data                     // Declare storage
        .align  8                 // Desired alignment
X2:     data8   0x12345678        // Number to convert
A2:     .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                 // Leaf procedure can save
        .save   ar.lc, r31        //  the caller's ar.lc
        mov     r31 = ar.lc       //   in a scratch register
        .body                     // Now we really begin...
first:  add     r11 = @gprel(STACK),gp  // r11 -> stack
        movl    r21 = DOT8        // 0.8 reciprocal factor
new:    add     r15 = @gprel(X2),gp;;   // r15 -> input
        ld8     r9 = [r15]        // Get number to convert
        st8     [r11] = r0,1;;    // Push 0 as a flag
again:  mov     r20 = r9          // Save previous quotient
        mov     ar.lc = W-1       // Traversals minus one
booth:  mov     r19 = 0           // Set bit n-1 to zero
        mov     r8 = r21          // Get reciprocal factor (R)
        mov     r9 = 0;;          // Set L to zero
cycle:  and     r22 = 0x1,r8;;    // Isolate lowest bit of R
        xor     r23 = r19,r22;;   // r23 = whether to act
        cmp.ne  p6,p0 = 0,r23     // p6 = whether to act
        mov     r19 = r22;;       // Bit n-1 for next time
   (p6) cmp.eq.unc p7,p8 = 0,r22;;  // Add, subtract, nop?
   (p7) add     r9 = r9,r20       // Add X to L
   (p8) sub     r9 = r9,r20;;     // Subtract X from L
        shrp    r8 = r9,r8,1      // New R of shifted LR
        shr     r9 = r9,1         // New L of shifted LR
        br.cloop.sptk.few cycle;; // More cycles?
nosign: add     r9 = r9,r20;;     // Add X to L
        shr.u   r9 = r9,3;;       // r9 = quotient = r17/10
        shladd  r3 = r9,2,r9;;    // r3 = 5*quotient
        add     r3 = r3,r3;;      // r3 = 10*quotient now
        sub     r3 = r20,r3;;     // r3 = remainder now
        or      r3 = 0x30,r3;;    // Make into ASCII char
        st1     [r11] = 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     r11 = -2,r11      // Skip latest char
        add     r16 = @gprel(A2),gp;;    // r16 -> output
move:   st1     [r16] = r3,1      // Move one character
        ld1     r3 = [r11],-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 A2 area
        st1     [r16] = r0        // Make A2 into stringz
        add     r11 = 1,r11       // Fix stack pointer
done:   mov     r8 = r0           // Signal all is normal
        mov     ar.lc = r31       // Restore caller's ar.lc
        br.ret.sptk.many b0;;     // Back to command line
        .endp   main              // Mark end of procedure