You might want to run this through the MPLAB simulator to see how it works.
Code:
   WordA  VAR WORD BANK0 SYSTEM
   WordB  VAR WORD BANK0 SYSTEM
   WordC  VAR WORD BANK0 SYSTEM
   Counts VAR BYTE BANK0 SYSTEM

   GOTO Main        ' jump to Main

   ' shifts bits left from WordA to WordB to WordC with highest bit
   ' in WordC being trashed.
ASM
Rotate  macro
    rlf WordA,f     ; msb of lowbyte into carry
    rlf WordA+1,f   ; carry into lsb of highbyte, msb of highbyte into carry
    rlf WordB,f     ; carry into lsb of lowbyte, msb of lowbyte into carry
    rlf WordB+1,f   ; carry into lsb of highbyte, msb of highbyte into carry
    rlf WordC,f     ; carry into lsb of lowbyte, msb of lowbyte into carry
    rlf WordC+1,f   ; carry into lsb of highbyte, msb of highbyte into carry
    bcf STATUS,C    ; trash msb of WordC to prevent shifting into WordA lsb
    decfsz Counts,f ; decrement shift counter
    goto $-D'8'     ; keep shifting until Counts = 0
    endm
ENDASM


Main:
    ' starting 48-bit value = 1
    WordA = 1     ' load low word
    WordB = 0     ' load mid word
    WordC = 0     ' load high word
    Counts = 47   ' shift 48-bit value left by Counts
    @ Rotate      ' do it
    ' resulting 48-bit value = $800000000000
    
Here:
    GOTO Here   ' sit & spin after test
    END
This can be expanded to work on any number of variables. The only real limitation is available RAM &
PBP system variables.