// BACKWARD     Print a string backwards
// This program pauses for the user to enter a line
// of text, and prints that text backwards.

        NL      = 0xa             // Newline character
        LEN     = 96              // Line length allowed
        .global chrget,chrput     // External references
        .type   chrget,@function  //  and their
        .type   chrput,@function  //   types
        .data                     // Declare storage
        .align  8                 // Desired alignment
text:   .skip   LEN               // Storage size (<=2^^13)
        .text                     // Section for code
        .align  32                // Desired alignment
        .global main              // These three lines
        .proc   main              //  mark the mandatory
main:                             //   'main' program entry
        .prologue 12,r33          // rp, ar.pfs @r33+
        .save   ar.pfs,r34        // Previous function state
        alloc   r34 = ar.pfs,0,6,1,0  // 6 locals, 1 outgoing
        .save   rp,r33            // Say where we store
        mov     r33 = b0          //  the return address
        .body                     // End of prologue
first:                            // Now we really begin...
        addl    r35 = @gprel(text),gp;;  // r35 -> 1st byte
        add     r37 = (LEN-1),r35 // r37 -> last byte
        mov     r36 = r35         // r36 = moving pointer
        mov     r32 = r1          // Save gp across calls
iloop:  br.call.sptk.many b0=chrget  // Get one character
        mov     r1 = r32          // Restore gp
        cmp.ne  p6,p0 = NL,r8;;   // Store unless NL char
  (p6)  cmp.leu.unc p7,p0 = r36,r37;; // Space remaining?
  (p7)  st1     [r36] = r8,1      // Store; bump pointer
  (p7)  br.cond.sptk.few iloop;;  // Go get next character
        add     r36 = -1,r36;;    // Decrement the pointer
        br.cond.sptk.few otest    // First-time test
oloop:  ld1     r38 = [r36],-1    // r38 = character to send
        br.call.sptk.many b0=chrput;;  // Put one character
        mov     r1 = r32          // Restore gp
otest:  cmp.geu p6,p0 = r36,r35   // If more chars remain,
  (p6)  br.cond.sptk.few oloop    //  go get next character
        mov     r38 = NL          // r38 = newline to send
        br.call.sptk.many b0=chrput  // Put one character
        mov     r1 = r32          // Restore gp
done:   mov     r8 = 0            // Signal all is normal
        mov     ar.pfs = r34      // Restore previous state
        mov     b0 = r33          // Restore exit address
        br.ret.sptk.many b0;;     // Back to command line
        .endp   main              // Mark end of procedure