      INTEGER, PARAMETER :: small=1, med=2, big=3
      REAL(wp) :: a(3), comp(3), ymin, xi, term, t
      INTEGER :: i, elem

      res=zero

! Fast return
      IF (n<=0 .OR. incx<=0) THEN
        RETURN
      END IF

      a = zero
      comp = zero
      DO i=1,(n-1)*incx+1,incx
        xi=ABS(x(i))

        IF(xi > bu) THEN
          elem = big
          term = xi*rsu
        ELSE IF (xi < b) THEN
          elem = small
          term = xi*rs
        ELSE
          elem = med
          term = xi
        END IF
        comp(elem)=comp(elem)+term*term
        t = a(elem)
        a(elem) = t + comp(elem)
        comp(elem) = (t-a(elem)) + comp(elem)

      END DO

      IF (a(big) > zero) THEN
        a(big) = SQRT(a(big))
        IF (a(big) > oflimit) THEN
! An overflow has really occurred
          res = ieee_value(res, ieee_positive_inf)
          RETURN
        ENDIF
        IF (a(med) == zero) THEN
          res = a(big)*su
          RETURN
        ELSE
          a(med) = SQRT(a(med))
          res = a(big)*su
        END IF
         
! There is no way that both a(big) and a(small) can both be 
! usefully > zero
      ELSE IF (a(small) > zero) THEN
        a(small) = SQRT(a(small))
        IF (a(med) == zero) THEN
          res = a(small)*s
          RETURN
        ELSE
          a(med) = SQRT(a(med))
          res = a(small)*s
        END IF
      ELSE
        res = SQRT(a(med))
        RETURN
      END IF

! There may still be a contribution from a(med) that will count
! towards the correct value of the return value
      ymin = MIN(a(med), res)
      res = MAX(a(med), res)
      IF (ymin > sqrteps*res) THEN
        res = res*SQRT(one+(ymin/res)*(ymin/res))
      END IF
