OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 44 to Rev 45
    Reverse comparison

Rev 44 → Rev 45

/zipcpu/trunk/sw/lib/mpy32u.S
0,0 → 1,27
mpy32u: ; unsigned R0 * unsigned R1 -> unsigned R0:R1
PUSH R2
PUSH R3
PUSH R4
MOV R0,R2
MULU R1,R2 ; R2 = Low order bits, low(R0) * low(R1)
MOV R0,R3
LSR 16,R3 ; Put high order bits in lower half of R3
MULU R1,R3 ; R3 = Mid order bits, high(R0) * low(R1)
LSR 16,R1 ; R1 = High order bits of R1, being done w/ low order
MOV R1,R4 ;
MUL R0,R4 ; R4 = Mid order bits, low(R0) * high(R1)
LSR 16,R0
MULU R1,R0 ; R0 = High order bits, high(R0) * high(R1)
ADD R3,R4 ; R4 = sum of mid order bits
ADD.C 0x010000,R0 ; Add in the carry (if it happened)
MOV R4,R3
LSR 16,R3
ADD R3,R0 ; R0 = high order bits plus high order mid-bits
LSL 16,R4
ADD R4,R2 ; R2 = low order bits plus low order mid-bits
ADD.C 1,R0 ; Add in the carry to R0 (if it happened)
MOV R2,R1 ; Place low order bits into R1
POP R4
POP R3
POP R2
RET
/zipcpu/trunk/sw/lib/divs.S
0,0 → 1,44
;
; DIVS
;
; Given R0,R1, computer R0 = R0/R1 and R1 = R0%R1 for signed R0,R1.
; We'll call R0 (input) x, R1(input) y, result is such that
; R0 * y + R1 = x. Now let's work through our signs with an example
; where x = +/- 22, and y = +/- 4:
;
; x y
; + + No change, just call divu
; - + (x=-22,y= 4,R0=-5,R1=-2)
; + - (x= 22,y=-4,R0=-5,R1= 2)
; - - (x=-22,y=-4,R0= 5,R1=-2)
;
;
;
divs: ; Given R0,R1, computer R0 = R0/R1 and R1 = R0%R1 for signed R0,R1
SUB 2,SP
; (stall)
STO R3,2(SP)
;
CLR R3 ; Keep track of resulting sign in R2
TST -1,R0 ; Is R0 negative?
MOV ret_div32s(PC),R2
LLO.LT 3,R3 ; If so, resulting sign will be negative, and
NEG.LT R0 ; then we negate R0 (R0 = ABS(R0))
MOV.LT divu_divs_return(PC),R2
TST -1,R1 ; Is R1 negative?
XOR.LT 1,R3 ; If so, result will be opposite sign of before
NEG.LT R1 ; Now we get R1=ABS(R1)
MOV.LT divu_divs_return(PC),R2
STO R2,1(SP)
BRA divu ; Do our unsigned multiply
; JSR divu ; Do our unsigned multiply
divu_divs_return:
TST 1,R3 ; Check resulting sign
NEG.NE R0 ; Need to flip the sign of our result
TST 2,R3 ; Now, if R1 was originally negative
NEG.NE R1 ; Then negate R1
ret_div32s:
LOD 2(SP),R3
ADD 2,SP
RETN
 
/zipcpu/trunk/sw/lib/divu.S
0,0 → 1,98
;
;
;
;
divu: ; Given R0,R1, computer R0 = R0/R1 and R1 = R0%R1
TST -1,R1
; BNZ divu_valid_divide
CLR.Z R0 ; Should be a divide by zero error / trap
RETN.Z
divu_valid_divide:
SUB 1,SP
STO R3,1(SP)
;
LDI 1,R2 ; Here's where we record the bit we are working on
CLR R3 ; Here's where we build our result
; Our original loop rejoin point, before a touch of unrolling
CMP R1,R0
BRC divu_prep_next_bit
TST -1,R1
BLT divu_top_bit_set
divu_rotate_up_r1:
LSL 1,R2
LSL 1,R1
/*
CMP R1,R0
BRC divu_prep_next_bit
TST -1,R1
BGT divu_rotate_up_r1
*/
BLT divu_top_bit_set
CMP R1,R0
BRC divu_prep_next_bit
;
LSL 1,R2
LSL 1,R1
BLT divu_top_bit_set
CMP R1,R0
BRC divu_prep_next_bit
;
LSL 1,R2
LSL 1,R1
BLT divu_top_bit_set
CMP R1,R0
BRC divu_prep_next_bit
;
LSL 1,R2
LSL 1,R1
BLT divu_top_bit_set
CMP R1,R0
BRC divu_prep_next_bit
BRA divu_rotate_up_r1
 
divu_top_bit_set:
CMP R1,R0
BRC divu_prep_next_bit
SUB R1,R0
OR R2,R3
divu_prep_next_bit:
LSR 1,R1
LSR 1,R2
BZ divu_record_result
;
divu_next_loop:
CMP R1,R0 ;
SUB.GE R1,R0 ; We also switch to signed arithmetic, since
OR.GE R2,R3 ; after the first bit, we are signed
LSR 1,R1
LSR 1,R2
BZ divu_record_result
;
CMP R1,R0
SUB.GE R1,R0
OR.GE R2,R3
LSR 1,R1
LSR 1,R2
BZ divu_record_result
;
CMP R1,R0
SUB.GE R1,R0
OR.GE R2,R3
LSR 1,R1
LSR 1,R2
BZ divu_record_result
;
CMP R1,R0
SUB.GE R1,R0
OR.GE R2,R3
LSR 1,R1
LSR 1,R2
BNZ divu_next_loop
 
divu_record_result:
MOV R0,R1
MOV R3,R0
LOD 1(SP),R3
ADD 1,SP
RETN
 
/zipcpu/trunk/sw/lib/mpy32s.S
0,0 → 1,22
; We could build mul32s (32-bit signed multiply) as
mpy32s:
PUSH R2
CLR R2 ; Keep track of resulting sign in R2
TST R0 ; Is R0 negative?
XOR.LT #1,R2 ; If so, resulting sign will be negative, and
NEG.NZ R0 ; then we negate R0 (R0 = ABS(R0))
TST R1 ; Is R1 negative?
XOR.LT #1,R2 ; If so, result will be opposite sign of before
TST R1 ; Need to retest since xor modified flags
NEG.LT R1 ; Now we get R1=ABS(R1)
JSR mpy32u ; Do our unsigned multiply
CMP R2 ; Check resulting sign
BZ ret_mul32s ; If positive, do nothing more
NOT R0 ; If negative, negate the result
NOT R1
ADD $1,R1
ADD.C $1,R0
ret_mul32s:
POP R2
RET
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.