URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/zipcpu/trunk/sw
- from Rev 34 to Rev 36
- ↔ Reverse comparison
Rev 34 → Rev 36
/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 |
/lib/divs.S
0,0 → 1,36
; |
; 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 |
PUSH R2 |
CLR R2 ; Keep track of resulting sign in R2 |
TST -1,R0 ; Is R0 negative? |
LDI 3,R2 ; If so, resulting sign will be negative, and |
NEG.NZ R0 ; then we negate R0 (R0 = ABS(R0)) |
TST -1,R1 ; Is R1 negative? |
XOR.LT 1,R2 ; If so, result will be opposite sign of before |
TST -1,R1 ; Need to retest since xor modified flags |
NEG.LT R1 ; Now we get R1=ABS(R1) |
JSR divu ; Do our unsigned multiply |
TST 1,R2 ; Check resulting sign |
NEG.NE R0 ; Need to flip the sign of our result |
TST 2,R2 ; Now, if R1 was originally negative |
NEG.LT R1 ; Then negate R1 |
ret_div32s: |
POP R2 |
RET |
|
|
/lib/divu.S
0,0 → 1,42
; |
; |
; |
; |
divu: ; Given R0,R1, computer R0 = R0/R1 and R1 = R0%R1 |
TST R1 |
BNZ divu_valid_divide |
CLR R0 ; Should be a divide by zero error / trap |
RET |
divu_valid_divide: |
PUSH R2 |
PUSH R3 |
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_top_bit_set |
TST -1,R1 |
BLT divu_top_bit_set |
divu_rotate_up_r1: |
LSL 1,R2 |
LSL 1,R1 |
CMP R1,R0 |
BRC divu_top_bit_set |
TST -1,R1 |
BGT divu_rotate_up_r1 |
divu_top_bit_set: |
divu_next_bit: |
CMP R1,R0 |
BRC divu_prep_next_bit |
SUB R1,R0 |
OR R2,R3 |
divu_prep_next_bit |
LSR 1,R1 |
LSR 1,R2 |
BNZ divu_next_bit |
MOV R0,R1 |
MOV R3,R0 |
POP R3 |
POP R2 |
RET |
|
/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 |
|
/zasm/test.S
107,6 → 107,7
clr r5 |
clr r6 |
clr r7 |
clr r8 |
clr r9 |
clr r10 |
clr r11 |
184,6 → 185,7
clr r5 |
clr r6 |
clr r7 |
clr r8 |
clr r9 |
clr r10 |
clr r11 |
209,7 → 211,7
add $32,r0 |
add $-33,r0 |
bnz test_failure |
not.z r0 |
not r0 |
bge test_failure |
junk_address: |
clrf r0 |
300,10 → 302,11
.dat __here__+0x0100000+5 |
test_start: |
ldi $0x01000,r11 |
ldi -1,r10 |
lod test_data+pc,pc |
clr r11 |
clr r10 |
noop |
cmp $0,r11 |
cmp $0,r10 |
trap.z r11 |
add $1,r0 |
add $1,r0 |
530,8 → 533,8
// Now, let's test whether or not we can handle a subroutine |
#ifdef PUSH_TEST |
reverse_bit_order: |
PUSH(R1,SP) |
PUSH(R2,SP) |
PUSH(R1,SP) ; R1 will be our loop counter |
PUSH(R2,SP) ; R2 will be our accumulator and eventual result |
LDI 32,R1 |
CLR R2 |
reverse_bit_order_loop: |
/zasm/zasm.y
37,6 → 37,7
|
%{ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "asmdata.h" |
|
419,6 → 420,7
#include <sys/stat.h> |
#include <sys/fcntl.h> |
#include <assert.h> |
#include <string> |
|
OBJFILE objcode; |
|
499,7 → 501,12
FILE *ppout; |
pid_t zpp_pid; |
int zpp_status; |
std::string inclist; |
if (NULL != getenv("ZIPINC")) |
inclist = getenv("ZIPINC"); |
|
printf("Original INCLIST = %s\n", inclist.c_str()); |
|
master_input_filename = NULL; |
|
// Find what directory zasm is in, so that we can find zpp when |
521,7 → 528,22
skp++; |
} else if (argv[argn+skp][1] == 'E') |
preprocess_only = true; |
else if (argv[argn+skp][1] == 'd') |
else if (argv[argn+skp][1] == 'I') { |
if (argv[argn+skp][2]) { |
if (inclist.size() != 0) { |
inclist += std::string(":"); |
inclist += &argv[argn+skp][2]; |
} else |
inclist = &argv[argn+skp][2]; |
} else if (argn+skp+1<argc) { |
if (inclist.size() != 0) { |
inclist += std::string(":"); |
inclist += &argv[argn+skp+1][2]; |
} else |
inclist = &argv[argn+skp+1][2]; |
argn++; |
} |
} else if (argv[argn+skp][1] == 'd') |
yydebug = 1; |
else if (argv[argn+skp][1] == 'h') { |
usage(); |
540,6 → 562,7
} |
} |
} |
printf("New INCLIST = %s\n", inclist.c_str()); |
|
if (preprocess_only) { |
objcode.open("/dev/null"); |
554,6 → 577,7
objcode.open(zout_fname); |
} |
|
setenv("ZIPINC",inclist.c_str(), 1); |
master_input_filename = NULL; |
|
if (argc > 0) { |
/zasm/asmdata.cpp
378,7 → 378,10
break; |
case OP_NEG: |
if (m_cond != zp.ZIPC_ALWAYS) { |
yyerror("Illegal operation: Conditional negate. Negates cannot handle conditions"); |
LLINE *lln = new LLINE; |
lln->addline(new ILINE(zp.op_mov(m_cond,-1,m_opb,m_opb))); |
lln->addline(new ILINE(zp.op_not(m_cond,m_opb))); |
return lln; |
} else { |
LLINE *lln = new LLINE; |
lln->addline(new ILINE(zp.op_not(m_opb))); |
/zasm/zpp.l
662,9 → 662,40
BUFSTACK(const char *fname) { |
m_fp = fopen(fname, "r"); |
if (!m_fp) { |
fprintf(stderr, "Cannot open %s\n", fname); |
perror("O/S Err:"); |
exit(-1); |
char *pathptr = getenv("ZIPINC"); |
if (!pathptr) { |
fprintf(stderr, "Cannot open %s\n", fname); |
perror("O/S Err:"); |
exit(-1); |
} else { |
char *dptr, *colonp; |
char *pathcpy = new char[strlen(pathptr)+8192]; |
strcpy(pathcpy, pathptr); |
|
fprintf(stderr, "ZIPINC := %s\n", pathptr); |
dptr = pathptr; |
while((!m_fp)&&(NULL != (colonp = strchr(dptr, ':')))) { |
strncpy(pathcpy, dptr, colonp-pathptr); |
strcat(pathcpy, "/"); |
strcat(pathcpy, fname); |
fprintf(stderr, "Looking for include file, %s\n", pathcpy); |
if (access(fname, R_OK)==0) |
m_fp = fopen(pathcpy, "r"); |
dptr = colonp+1; |
} if ((!m_fp)&&(*dptr)) { |
strcpy(pathcpy, dptr); |
strcat(pathcpy, "/"); |
strcat(pathcpy, fname); |
fprintf(stderr, "Looking for include file, %s\n", pathcpy); |
m_fp = fopen(pathcpy, "r"); |
} if (!m_fp) { |
fprintf(stderr, "Cannot open %s\n", fname); |
perror("O/S Err:"); |
exit(-1); |
} |
|
delete[] pathcpy; |
} |
} |
|
if (curbs) |
/zasm/sys.i
44,7 → 44,7
sys.ccn equ 0x004 |
sys.ccc equ 0x002 |
sys.ccz equ 0x001 |
sys.bu.pic equ 0x000 |
sys.bus.pic equ 0x000 |
sys.bus.wdt equ 0x001 |
sys.bus.cache equ 0x002 |
sys.bus.ctrpic equ 0x003 |
120,12 → 120,10
ADD 1,SP |
#define RET LOD 1(SP),PC |
#define SAVE_USER_CONTEXT(DR,AR) \ |
MOV -16(uSP),AR \ |
MOV -15(uSP),AR \ |
MOV uPC,DR \ |
STO DR,16(AR) \ |
STO DR,15(AR) \ |
MOV uCC,DR \ |
STO DR,15(AR) \ |
MOV uSP,DR \ |
STO DR,14(AR) \ |
MOV uR12,DR \ |
STO DR,13(AR) \ |
181,10 → 179,8
LOD 13(AR),DR \ |
MOV DR,uR12 \ |
LOD 14(AR),DR \ |
MOV DR,uSP \ |
MOV DR,uCC \ |
LOD 15(AR),DR \ |
MOV DR,uCC \ |
LOD 16(AR),DR \ |
MOV DR,uPC |
#define READ_USER_TRAP(RG) \ |
MOV uCC,RG \ |