0 Members and 2 Guests are viewing this topic.
.equ SHIFT_THRESH, 5 | XXX the exact optimal value needs to be figured out| unsigned long long sr64(unsigned long long, unsigned);sr64: move.l (4,%sp),%d0 move.l (8,%sp),%d1 move.w (12,%sp),%d2| shift right a 64-bit number| input:| %d0:%d1 = 64-bit number (%d0 is upper 32 bits)| %d2.w = shift amount (unsigned)| output:| %d0:%d1, shiftedsr64_reg: cmp #SHIFT_THRESH,%d2 blo 8f cmp #32,%d2 bhs 5f ror.l %d2,%d0 lsr.l %d2,%d1 | 00..xx (upper bits cleared) move.l %d3,-(%sp) | compute masks moveq #-1,%d3 lsr.l %d2,%d3 | 00..11 (lower bits) move.l %d3,%d2 not.l %d2 | 11..00 (upper bits) and.l %d0,%d2 | only upper bits from %d0 or.l %d2,%d1 | put upper bits from %d0 into %d1 and.l %d3,%d0 | clear upper bits in %d0 move.l (%sp)+,%d3 rts | shift amount is >= 325: cmp #64,%d2 bhs 6f sub #32,%d2 move.l %d0,%d1 lsr.l %d2,%d1 moveq #0,%d0 rts | shift amount < threshold7: | shift right one bit lsr.l #1,%d0 roxr.l #1,%d18: dbra %d2,7b rts| unsigned long long sl64(unsigned long long, unsigned);sl64: move.l (4,%sp),%d0 move.l (8,%sp),%d1 move.w (12,%sp),%d2| shift left a 64-bit number| input:| %d0:%d1 = 64-bit number (%d0 is upper 32 bits)| %d2.w = shift amount (unsigned)| output:| %d0:%d1, shiftedsl64_reg: cmp #SHIFT_THRESH,%d2 blo 8f cmp #32,%d2 bhs 5f rol.l %d2,%d1 lsl.l %d2,%d0 | xx..00 (lower bits cleared) move.l %d3,-(%sp) | compute masks moveq #-1,%d3 | mask lsl.l %d2,%d3 | 11..00 (upper bits) move.l %d3,%d2 not.l %d2 | 00..11 (lower bits) and.l %d1,%d2 | only lower bits from %d1 or.l %d2,%d0 | put lower bits from %d1 into %d0 and.l %d3,%d1 | clear lower bits in %d1 move.l (%sp)+,%d3 rts | shift amount is >= 325: cmp #64,%d2 bhs 6f sub #32,%d2 move.l %d1,%d0 lsl.l %d2,%d0 moveq #0,%d1 rts | shift amount is >= 646: moveq.l #0,%d0 move.l %d0,%d1 rts | shift amount < threshold7: | shift left one bit lsl.l #1,%d1 roxl.l #1,%d08: dbra %d2,7b rts