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

Subversion Repositories zipcpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /zipcpu/trunk
    from Rev 26 to Rev 25
    Reverse comparison

Rev 26 → Rev 25

/sw/zipdbg/README File deleted
/sw/zasm/test.S
48,7 → 48,7
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
#include "sys.i"
// #include "sys.i"
sys.bus equ 0xc0000000
sys.breaken equ 0x080
sys.step equ 0x040
58,7 → 58,6
sys.ccn equ 0x004
sys.ccc equ 0x002
sys.ccz equ 0x001
sys.cctrap equ 0x200
sys.bu.pic equ 0x000
sys.bus.wdt equ 0x001
sys.bus.cache equ 0x002
76,14 → 75,6
sys.bus.uastl equ 0x00e
sys.bus.ustl equ 0x00f
#define DO_TEST_ASSEMBLER
#define BREAK_TEST
#define OVERFLOW_TEST
#define CARRY_TEST
#define LOOP_TEST
#define SHIFT_TEST
#define TRAP_TEST
#define MPY_TEST
// #define PUSH_TEST
test:
#ifdef DO_TEST_ASSEMBLER
; We start out by testing our assembler. We give it some instructions, which
94,7 → 85,6
bra continue_test_with_testable_instructions
break
wait
break
busy
rtu
continue_test_with_testable_instructions:
216,52 → 206,43
lod junk_address(pc),r6
cmp r5,r6
bnz test_failure
; Now, let's test whether or not our LSR and carry flags work
ldi -1,r0 ; First test: shifting all the way should yield zero
lsr 32,r0
cmp 0,r0
bnz test_failure
ldi -1,r0 ; Second test: anything greater than zero should set
lsr 0,r0 ; the carry flag
bc test_failure
lsr 1,r0
tst sys.ccc,cc
bz test_failure
lsr 31,r0
tst sys.ccc,cc
bz test_failure
lsr 1,r0
bc test_failure
; Now repeat the above tests, looking to see whether or not ASR works
ldi -1,r0
asr 32,r0
cmp -1,r0
bnz test_failure
ldi -1,r0
asr 0,r0
bc test_failure
cmp -1,r0
bnz test_failure
asr 1,r0
tst sys.ccc,r14
bz test_failure
asr 30,r0
tst sys.ccc,r14
bz test_failure
#endif
 
#ifdef NOONE // Testing comments after ifdef
#else ; After else
#endif /* and after endif */
 
#ifdef BREAK_TEST
breaktest:
bra breaksupervisor
breakuser:
clr r0
mov 1+r0,r1
mov 1+r1,r2
mov 1+r2,r3
break ; At address 0x0100097
mov 1+r4,r5
mov 1+r5,r6
clr cc
busy
breaksupervisor:
ldi -1,r0
mov breakuser(pc),upc
rtu ; Should just keep returning immediately
mov upc,r0
rtu
rtu
mov upc,r1
cmp r0,r1
bnz test_failure
#endif
 
#ifdef TRAP_TEST
traptest:
bra traptest_supervisor
busy
traptest_user:
trap 0
busy
traptest_supervisor:
mov traptest_user(pc),upc
rtu
mov cc,r0
tst sys.cctrap,r0
bz test_failure
#endif
 
testbench:
// Let's build a software test bench.
ldi $c0000000h,r12 ; Set R12 to point to our peripheral address
271,7 → 252,7
sto r0,(r12)
rtu
mov ucc,r0
cmp sys.cctrap,r0
tst -256,r0
bnz test_failure
halt
// Go into an infinite loop if the trap fails
288,7 → 269,7
test_data:
.dat __here__+0x0100000+5
test_start:
ldi $0x01000,r11
ldi $0x0100,r11
lod test_data+pc,pc
clr r11
noop
297,9 → 278,8
add $1,r0
add $1,r0
 
#ifdef OVERFLOW_TEST
// Let's test whether overflow works
ldi $0x02000,r11
ldi $0x0200,r11
ldi $-1,r0
lsr $1,r0
add $1,r0
307,7 → 287,7
trap r11
first_overflow_passes:
// Overflow set from subtraction
ldi $0x03000,r11
ldi $0x0300,r11
ldi $1,r0
rol $31,r0 ; rol $31,r0
sub $1,r0
315,7 → 295,7
trap r11
subtraction_overflow_passes:
// Overflow set from LSR
ldi $0x04000,r11
ldi $0x0400,r11
ldi $1,r0
rol $31,r0 ; rol $31,r0
lsr $1,r0
323,7 → 303,7
trap r11
lsr_overflow_passes:
// Overflow set from LSL
ldi $0x05000,r11
ldi $0x0500,r11
ldi $1,r0
rol $30,r0
lsl $1,r0
331,34 → 311,28
trap r11
lsl_overflow_passes:
// Overflow set from LSL, negative to positive
ldi $0x06000,r11
ldi $0x0600,r11
ldi $1,r0
rol $31,r0
lsl $1,r0
bv second_lsl_overflow_passes
trap r11
#endif // OVERFLOW_TEST
#ifdef CARRY_TEST
second_lsl_overflow_passes:
// Test carry
ldi $0x07000,r11
ldi $0x0700,r11
ldi $-1,r0
add $1,r0
tst $2,cc
trap.z r11
// and carry from subtraction
ldi $0x08000,r11
clr r0
ldi $0x0800,r11
sub $1,r0
tst $2,cc
trap.z r11
#endif
 
#ifdef LOOP_TEST
 
// Let's try a loop: for i=0; i<5; i++)
// We'll use R0=i, Immediates for 5
ldi $0x09000,r11
ldi $0x0800,r11
clr r0
for_loop:
noop
372,7 → 346,7
// R0 = 5; (from before)
// do {
// } while (R0 > 0);
ldi $0x0a000,r11
ldi $0x0900,r11
bgt_loop:
noop
sub $1,r0
394,7 → 368,7
// R0 = 5; (from before)
// do {
// } while (R0 > 0);
ldi $0x0b000,r11
ldi $0x0a00,r11
bra mem_loop_test
loop_var:
.dat 0
412,44 → 386,9
bgt mem_loop
cmp $5,r2
trap.ne r11
#endif
 
#ifdef SHIFT_TEST
; Now, let's test whether or not our LSR and carry flags work
ldi $0x0c000,r11
ldi -1,r0 ; First test: shifting all the way should yield zero
lsr 32,r0
cmp 0,r0
bnz test_failure
ldi -1,r0 ; Second test: anything greater than zero should set
lsr 0,r0 ; the carry flag
bc test_failure
lsr 1,r0
tst sys.ccc,cc ; FAILS HERE!!! @0x010007c
bz test_failure
lsr 31,r0
tst sys.ccc,cc
bz test_failure
lsr 1,r0
bc test_failure
; Now repeat the above tests, looking to see whether or not ASR works
ldi -1,r0
asr 32,r0
cmp -1,r0
bnz test_failure
ldi -1,r0
asr 0,r0
bc test_failure
cmp -1,r0
bnz test_failure
asr 1,r0
tst sys.ccc,r14
bz test_failure
asr 30,r0
tst sys.ccc,r14
bz test_failure
 
// Let's test whether LSL works
ldi $0x0b00,r11
ldi 0x035,r2
lsl 8,r2
ldi 0x03500,r1
460,40 → 399,7
or r0,r2
cmp 0x03574,r2
trap.ne r11
#endif
 
#ifdef MPY_TEST
 
// We have two multiply instructions. Let's see if those work
ldi $0x0d000,r11 // Mark our test
ldi 23171,r0 // = sqrt(2)/2 * 32768
mpyu r0,r0 // Should = 2/4 * 2^30 = 2^29 or thereabouts
ldi 536895241,r2
cmp r0,r2
trap.ne r11
ldi 0x0ffff,r0
mpyu r0,r0
ldi 0xfffe0001,r1
cmp r1,r0
trap.ne r11
ldi 0x08001,r0
ldi 0x07fff,r1
mpys r0,r1 // FAILS: result is 0x008001 ??? (pipeline prob)
ldi 0x3fff0001,r2
neg r2
cmp r2,r1 // @0x010011c
trap.ne r11 //TRAP FAILS TO TRIGGER ????? (R2=0x0c000ffff,R1=0x0008001 -- did mpy even happen?)
mpys r0,r0 // FAILS: result is 0x40010001
ldi 0x3fff0001,r2
cmp r2,r0
trap.ne r11 // TRAP FAILS TO TRIGGER AGAIN
ldi 0x08000,r0
mpys r0,r0 // R0 now equals 0x40000000
ldi 0x40000000,r1
cmp r0,r1
trap.ne r11
#endif
// Return success / Test the trap interrupt
clr r11
trap r11
/sw/zasm/zopcodes.cpp
131,10 → 131,8
"LDILO",0xff100000, 0x4f000000, REGFIELD(16),OPUNUSED, OPUNUSED, IMMFIELD(16,0), BITFIELD(3,21),
"LDIHI",0xff100000, 0x4f100000, REGFIELD(16),OPUNUSED, OPUNUSED, IMMFIELD(16,0), BITFIELD(3,21),
//
"MPYU", 0xf01f0000, 0x400f0000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(15,0), BITFIELD(3,21),
"MPYU", 0xf0100000, 0x40000000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
"MPYS", 0xf01f0000, 0x401f0000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(15,0), BITFIELD(3,21),
"MPYS", 0xf0100000, 0x40100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
"MPY", 0xf0100000, 0x40000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
"MPY", 0xf0100000, 0x40100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
//
"ROL", 0xf0100000, 0x50000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(5,0), BITFIELD(3,21),
"ROL", 0xf0100000, 0x50100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(5,0), BITFIELD(3,21),
/sw/zasm/zasm.y
40,9 → 40,6
#include <string.h>
#include "asmdata.h"
 
#define DEFAULT_OUTPUT_FNAME "z.out"
#define YYDEBUG 1
 
extern "C" int yylex(void);
extern "C" int yyparse(void);
// extern "C" FILE *yyin;
78,13 → 75,6
%type <u_ln> bareop singlop dualop loadop storop line
%type <u_ast> expr value multident
 
%left BOOLEANOR
%left BOOLEANAND
%left BITWISEOR BITWISEXOR
%left BITWISEAND
%left PLUS MINUS
%left TIMES '/'
 
%% /* The grammar follows */
 
input:
412,7 → 402,6
 
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <assert.h>
424,8 → 413,9
if (linecp) fprintf(stderr, "Offending line was: %s\n", linecp);
}
 
FILE *run_preprocessor(pid_t &pid, const char *path = NULL, const char *zname = NULL) {
FILE *run_preprocessor(const char *path = NULL, const char *zname = NULL) {
int pipefd[2];
int pid;
 
if (pipe(pipefd)!=0) {
fprintf(stderr, "PIPE FAILED!\n");
477,26 → 467,11
return fdopen(pipefd[0], "r");
}
 
void usage(void) {
printf("USAGE: zasm [-h] [-d] [-E] [-o <out-fname>] <asm-file> [<asm-file> ]* ...\n");
printf("\t-d\tTurns on debugging in the parser\n");
printf("\t-E\tProduces preprocessor output only\n");
printf("\t-h\tDisplays this message\n");
printf("\t-o <out-fname>\tWrites the output to <out-fname>. The\n"
"\t\tdefault output file is \"" DEFAULT_OUTPUT_FNAME "\".\n");
 
printf("\t-I <dir>\tSearch <dir> for include files.\n");
}
 
int main(int argc, char **argv) {
int skp = 0;
const char *zout_fname = NULL;
char *path_to_zasm = NULL;
bool preprocess_only = false;
FILE *ppout;
pid_t zpp_pid;
int zpp_status;
 
master_input_filename = NULL;
 
// Find what directory zasm is in, so that we can find zpp when
518,35 → 493,16
skp++;
} else if (argv[argn+skp][1] == 'E')
preprocess_only = true;
else if (argv[argn+skp][1] == 'd')
yydebug = 1;
else if (argv[argn+skp][1] == 'h') {
usage();
exit(0);
}
 
skp++;
} argv[argn] = argv[argn+skp];
} argc -= skp;
 
if (zout_fname) {
for(int argn=0; argn<argc; argn++) {
if (strcmp(zout_fname, argv[argn])==0) {
fprintf(stderr, "ERR: Cowardly refusing to overwrite \'%s\'\n", zout_fname);
exit(-2);
}
}
}
 
if (preprocess_only) {
objcode.open("/dev/null");
if (zout_fname)
ppout = fopen(zout_fname, "w");
else
ppout = stdout;
} else {
if (!zout_fname)
zout_fname = DEFAULT_OUTPUT_FNAME;
zout_fname = "z.out";
 
objcode.open(zout_fname);
}
564,16 → 520,14
free(master_input_filename);
master_input_filename = strdup(argv[argn]);
if (preprocess_only) {
FILE *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
FILE *fp = run_preprocessor(path_to_zasm, master_input_filename);
int ch;
while(EOF != (ch = fgetc(fp)))
fputc(ch, ppout);
waitpid(zpp_pid, &zpp_status, WNOHANG);
fputc(ch, stdout);
} else {
yyrestart(run_preprocessor(zpp_pid, path_to_zasm, master_input_filename));
yyrestart(run_preprocessor(path_to_zasm, master_input_filename));
yylineno = 1;
yyparse();
waitpid(zpp_pid, &zpp_status, WNOHANG);
}
}
} else { // Run from Stdin
584,24 → 538,17
master_input_filename = strdup("(stdin)");
if (preprocess_only) {
int ch;
FILE *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
FILE *fp = run_preprocessor(path_to_zasm, master_input_filename);
while(EOF != (ch = fgetc(fp)))
fputc(ch, ppout);
waitpid(zpp_pid, &zpp_status, WNOHANG);
fputc(ch, stdout);
} else {
yyin = run_preprocessor(zpp_pid, NULL);
yyin = run_preprocessor(NULL);
yyrestart(yyin);
yyparse();
waitpid(zpp_pid, &zpp_status, WNOHANG);
}
}
 
if (0 != WEXITSTATUS(zpp_status)) {
if (!preprocess_only) {
objcode.close();
unlink(zout_fname);
}
} if (!objcode.reduce())
if (!objcode.reduce())
fprintf(stderr, "Not all symbols defined!\n");
}
 
/sw/zasm/zpp.l
137,12 → 137,11
<INNOTDEF>^"#else"[ \t]*((;|"//").*)?$ { BEGIN INDEF; }
<INNOTDEF>(.*) { }
<INDEF>^"#elsif"[ \t]* { BEGIN NVRDEF; }
<NVRDEF,NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*((;|"//").*)?$ { yy_pop_state(); }
<NVRDEF,NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*"/*" { BEGIN COMMENT; }
<NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*((;|"//").*)?$ { yy_pop_state(); }
<NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*"/*" { BEGIN COMMENT; }
<*>^"#endif"[ \t]* { fprintf(stderr, "ERR: Unknown endif!!\n");}
<INITIAL,INDEF>^"#struct"[ \t]* {
yy_push_state(GETSTRUCTID); structno = 0; }
<*>^"#"{ID}[ \t]* { fprintf(stderr, "ERR: Unrecognized preprocessor instruction, %s\n", yytext);}
<GETSTRUCTID>{ID}/[ \t\n;/] { BEGIN INSTRUCT;
structid = strdup(yytext);
}
161,20 → 160,11
}
<*>[ \t]*"//".*$ { /* Ignore (trailing) comment only lines */ }
<*>[ \t]*";".*$ { /* Ignore (trailing) comment only lines */ }
<*>"#warning".*$ { fprintf(stderr, "WARNING: %s\n", &yytext[8]); }
<*>"#error".*$ { fprintf(stderr, "ERROR: %s\n", &yytext[8]); exit(-1); }
<*>"/*" { yy_push_state(COMMENT); }
<*>[ \t]+ { ECHO; }
<*>\n { ECHO; yylineno++; mark_line(); }
/* <*>. { printf("Unmatched \'%c\'\n", yytext[0]); } */
<NVRDEF,NODEF,INDEF,INNOTDEF><<EOF>> { fprintf(stderr, "Unexpected EOF! Expecting #endif\n"); }
<IFDEFV><<EOF>> { fprintf(stderr, "Unexpected EOF! Expecting #endif\n"); }
<COMMENT><<EOF>> { fprintf(stderr, "Unexpected EOF! Expecting */\n"); }
<INSTRUCT><<EOF>> { fprintf(stderr, "Unexpected EOF! Expecting #endstruct\n"); }
<GETSTRUCTID><<EOF>> { fprintf(stderr, "Unexpected EOF! Expecting #struct ID, then #endstruct\n"); }
<DFA,DFV,DFV_EOL><<EOF>> { fprintf(stderr, "Unexpected EOF! Expecting end of line\n"); }
<INDEF_EOL,INNOTDEF_EOL><<EOF> { fprintf(stderr, "Unexpected EOF Expecting end of line, then #endif\n"); }
<INITIAL><<EOF>> { if (end_of_file()) yyterminate(); }
<<EOF>> { if (end_of_file()) yyterminate(); }
 
%%
 
397,12 → 387,6
fprintf(fp, "#line %d \"%s\"\n", yylineno, m_fname);
}
 
void markline(void) {
FILE *fp = yyout;
if (!fp) fp = stdout;
fprintf(fp, "#line %d\n", yylineno);
}
 
static void pop(void) {
// fprintf(stderr, "POP! (%s)\n", curbs->m_fname);
if (curbs)
417,9 → 401,7
const char *last_marked_file = NULL;
void mark_line(void) {
if ((yylineno != last_marked_line+1)||(BUFSTACK::curfilename != last_marked_file))
if (BUFSTACK::curfilename == last_marked_file)
BUFSTACK::curbs->markline();
else BUFSTACK::curbs->mark();
BUFSTACK::curbs->mark();
last_marked_line = yylineno;
last_marked_file = BUFSTACK::curfilename;
}
446,7 → 428,5
// delete bs;
}
}
 
return 0;
}
 
/sw/zasm/zasm.l
51,12 → 51,7
 
%%
 
"#line"[ \t]+[0-9]+[ \t]+[\"][^"]*[\"][ \t]*$ {
/* This should really be true *only* at the beginning of a line,
* however such line beginnings aren't matching. My guess is that
* the reason is my line copying code at the bottom that sucks up the
* newline for LEX. Hence, this is what we have.
*/
^"#line"[ \t]+[0-9]+[ \t]+[\"][^"]*[\"][ \t]*$ {
yylineno = atoi(&yytext[6]);
char *bg, *en;
bg = strchr(yytext, '\"')+1;
66,11 → 61,8
master_input_filename = new char[en-bg+2];
strcpy(master_input_filename, bg);
}
return '\n';
}
"#line"[ \t]+[0-9]+[ \t]*$ { yylineno = atoi(&yytext[6]); return '\n';}
^"#line".*$ { printf("WARNING: Unmatched #line: %s\n", yytext); return '\n'; }
"#line".*$ { printf("WARNING: Unmatched #line, not at beginnning: %s\n", yytext); return '\n'; }
^"#line"[ \t]+[0-9]+[ \t]+$ { yylineno = atoi(&yytext[6]); }
[uU][rR]1[0-5] { yylval.u_reg=(ZPARSER::ZIPREG)(26+yytext[3]-'0');return REG; }
[sS][rR]1[0-5] { yylval.u_reg=(ZPARSER::ZIPREG)(10+yytext[3]-'0');return REG; }
[rR]1[0-5] { yylval.u_reg=(ZPARSER::ZIPREG)(10+yytext[2]-'0');return REG; }
77,15 → 69,15
[uU][rR][0-9] { yylval.u_reg=(ZPARSER::ZIPREG)(16+yytext[2]-'0');return REG; }
[sS][rR][0-9] { yylval.u_reg=(ZPARSER::ZIPREG)( yytext[2]-'0');return REG; }
[rR][0-9] { yylval.u_reg=(ZPARSER::ZIPREG)( yytext[1]-'0');return REG; }
(?i:upc) { yylval.u_reg = ZPARSER::ZIP_uPC; return REG; }
(?i:spc) { yylval.u_reg = ZPARSER::ZIP_PC; return REG; }
(?i:pc) { yylval.u_reg = ZPARSER::ZIP_PC; return REG; }
(?i:ucc) { yylval.u_reg = ZPARSER::ZIP_uCC; return REG; }
(?i:scc) { yylval.u_reg = ZPARSER::ZIP_CC; return REG; }
(?i:cc) { yylval.u_reg = ZPARSER::ZIP_CC; return REG; }
(?i:usp) { yylval.u_reg = ZPARSER::ZIP_uSP; return REG; }
(?i:ssp) { yylval.u_reg = ZPARSER::ZIP_SP; return REG; }
(?i:sp) { yylval.u_reg = ZPARSER::ZIP_SP; return REG; }
[uU][pP][cC] { yylval.u_reg = ZPARSER::ZIP_uPC; return REG; }
[sS][pP][cC] { yylval.u_reg = ZPARSER::ZIP_PC; return REG; }
[pP][cC] { yylval.u_reg = ZPARSER::ZIP_PC; return REG; }
[uU][cC][cC] { yylval.u_reg = ZPARSER::ZIP_uCC; return REG; }
[sS][cC][cC] { yylval.u_reg = ZPARSER::ZIP_CC; return REG; }
[cC][cC] { yylval.u_reg = ZPARSER::ZIP_CC; return REG; }
[uU][sS][pP] { yylval.u_reg = ZPARSER::ZIP_uSP; return REG; }
[sS][sS][pP] { yylval.u_reg = ZPARSER::ZIP_SP; return REG; }
[sS][pP] { yylval.u_reg = ZPARSER::ZIP_SP; return REG; }
[bB][rR][aA] { yylval.u_op = OP_BRA; return BRANCHOP; }
[bB][rR][zZ] { yylval.u_op = OP_BZ; return BRANCHOP; }
[bB][zZ] { yylval.u_op = OP_BZ; return BRANCHOP; }
100,44 → 92,42
[bB][cC] { yylval.u_op = OP_BRC; return BRANCHOP; }
[bB][rR][vV] { yylval.u_op = OP_BRV; return BRANCHOP; }
[bB][vV] { yylval.u_op = OP_BRV; return BRANCHOP; }
(?i:clr) { yylval.u_op = OP_CLR; return SINGLOP; }
(?i:clrf) {yylval.u_op = OP_CLRF;return SINGLOP; }
(?i:int) { yylval.u_op = OP_TRAP;return SINGLOP; }
(?i:trap) {yylval.u_op = OP_TRAP;return SINGLOP; }
(?i:jmp) { yylval.u_op = OP_JMP; return SINGLOP; }
[cC][lL][rR] { yylval.u_op = OP_CLR; return SINGLOP; }
[cC][lL][rR][fF] {yylval.u_op = OP_CLRF;return SINGLOP; }
[iI][nN][tT] { yylval.u_op = OP_TRAP;return SINGLOP; }
[tT][rR][aA][pP] {yylval.u_op = OP_TRAP;return SINGLOP; }
[jJ][mM][pP] { yylval.u_op = OP_JMP; return SINGLOP; }
[lL][jJ][mM][pP] {yylval.u_op = OP_LJMP;return SINGLOP; }
(?i:neg) { yylval.u_op = OP_NEG; return SINGLOP; }
(?i:not) { yylval.u_op = OP_NOT; return SINGLOP; }
(?i:cmp) { yylval.u_op = OP_CMP; return DUALOP; }
(?i:tst) { yylval.u_op = OP_TST; return DUALOP; }
(?i:mov) { yylval.u_op = OP_MOV; return DUALOP; }
(?i:ldi) { yylval.u_op = OP_LDI; return LDIOP; }
[nN][oO][tT] { yylval.u_op = OP_NOT; return SINGLOP; }
[cC][mM][pP] { yylval.u_op = OP_CMP; return DUALOP; }
[tT][sS][tT] { yylval.u_op = OP_TST; return DUALOP; }
[mM][oO][vV] { yylval.u_op = OP_MOV; return DUALOP; }
[lL][dD][iI] { yylval.u_op = OP_LDI; return LDIOP; }
[lL][dD][iI][hH][iI] { yylval.u_op =OP_LDIHI; return LDHLOP; }
[lL][dD][iI][lL][oO] { yylval.u_op =OP_LDILO; return LDHLOP; }
(?i:mpyu) { yylval.u_op = OP_MPYU; return DUALOP; }
(?i:mpys) { yylval.u_op = OP_MPYS; return DUALOP; }
(?i:rol) { yylval.u_op = OP_ROL; return DUALOP; }
(?i:sub) { yylval.u_op = OP_SUB; return DUALOP; }
(?i:and) { yylval.u_op = OP_AND; return DUALOP; }
(?i:add) { yylval.u_op = OP_ADD; return DUALOP; }
(?i:or) { yylval.u_op = OP_OR; return DUALOP;; }
(?i:xor) { yylval.u_op = OP_XOR; return DUALOP; }
(?i:lsl) { yylval.u_op = OP_LSL; return DUALOP; }
(?i:asr) { yylval.u_op = OP_ASR; return DUALOP; }
(?i:lsr) { yylval.u_op = OP_LSR; return DUALOP; }
(?i:lod) { yylval.u_op = OP_LOD; return LOADOP; }
(?i:sto) { yylval.u_op = OP_STO; return STOROP; }
(?i:halt) { yylval.u_op = OP_HALT; return BAREOP; }
(?i:wait) { yylval.u_op = OP_HALT; return BAREOP; }
(?i:rtu) { yylval.u_op = OP_RTU; return BAREOP; }
(?i:nop) { yylval.u_op = OP_NOOP; return BAREOP; }
(?i:noop) { yylval.u_op = OP_NOOP; return BAREOP; }
(?i:break) { yylval.u_op = OP_BREAK; return BAREOP; }
(?i:brk) { yylval.u_op = OP_BREAK; return BAREOP; }
(?i:busy) { yylval.u_op = OP_BUSY; return BAREOP; }
(?i:equ) { return EQU; }
(?i:fill) { return FILL; }
(?i:word) { return WORD; }
[mM][pP][yY] { yylval.u_op = OP_MPY; return DUALOP; }
[rR][oO][lL] { yylval.u_op = OP_ROL; return DUALOP; }
[sS][uU][bB] { yylval.u_op = OP_SUB; return DUALOP; }
[aA][nN][dD] { yylval.u_op = OP_AND; return DUALOP; }
[aA][dD][dD] { yylval.u_op = OP_ADD; return DUALOP; }
[oO][rR] { yylval.u_op = OP_OR; return DUALOP;; }
[xX][oO][rR] { yylval.u_op = OP_XOR; return DUALOP; }
[lL][sS][lL] { yylval.u_op = OP_LSL; return DUALOP; }
[aA][sS][rR] { yylval.u_op = OP_ASR; return DUALOP; }
[lL][sS][rR] { yylval.u_op = OP_LSR; return DUALOP; }
[lL][oO][dD] { yylval.u_op = OP_LOD; return LOADOP; }
[sS][tT][oO] { yylval.u_op = OP_STO; return STOROP; }
[hH][aA][lL][tT] { yylval.u_op = OP_HALT; return BAREOP; }
[wW][aA][iI][tT] { yylval.u_op = OP_HALT; return BAREOP; }
[rR][tT][uU] { yylval.u_op = OP_RTU; return BAREOP; }
[nN][oO][pP] { yylval.u_op = OP_NOOP; return BAREOP; }
[nN][oO][oO][pP] { yylval.u_op = OP_NOOP; return BAREOP; }
[bB][rR][eE][aA][kK] { yylval.u_op = OP_BREAK; return BAREOP; }
[bB][rR][kK] { yylval.u_op = OP_BREAK; return BAREOP; }
[bB][uU][sS][yY] { yylval.u_op = OP_BUSY; return BAREOP; }
[eE][qQ][uU] { return EQU; }
[fF][iI][lL][lL] { return FILL; }
[wW][oO][rR][dD] { return WORD; }
"__"[hH][eE][rR][eE]"__" { return HERE; }
[\.][dD][aA][tT] { return WORD; }
[\.][zZ]/[ \t\n] { yylval.u_cond = ZPARSER::ZIPC_Z; return COND; }
155,27 → 145,6
"$"?[-]?[1-9][0-9]* { yylval.u_ival = strtoul(yytext+(((*yytext)=='$')?1:0),NULL,10);return INT;}
"$"?[-]?[1-9A-Fa-f][0-9A-Fa-f]*h {yylval.u_ival=strtoul(yytext+(((*yytext)=='$')?1:0),NULL,16); return INT;}
"$"?[-]?[0-7]+o { yylval.u_ival = strtoul(yytext+(((*yytext)=='$')?1:0),NULL, 8);return INT;}
"\'"[^\\\']"\'" { printf("Match char, %s\n", yytext); yylval.u_ival = yytext[1]&0x0ff; return INT; }
"\'\\"[abnr\\]"\'" {
yylval.u_ival = yytext[2];
if (yytext[2] == 'a') yylval.u_ival = '\a';
else if (yytext[2] == 'b') yylval.u_ival = '\b';
else if (yytext[2] == 'f') yylval.u_ival = '\f';
else if (yytext[2] == 'n') yylval.u_ival = '\n';
else if (yytext[2] == 'r') yylval.u_ival = '\r';
else if (yytext[2] == 't') yylval.u_ival = '\t';
else if (yytext[2] == 'v') yylval.u_ival = '\v';
else if (yytext[2] == '0') yylval.u_ival = '\0';
else if (yytext[2] == '\\') yylval.u_ival = '\\';
return INT; }
"\'"[^\\\'][^\\\']"\'" { yylval.u_ival = ((yytext[1]&0x0ff)<<8)+(yytext[2]&0x0ff); return INT; }
"\'"[^\\\'][^\\\'][^\\\']"\'" { yylval.u_ival = ((yytext[1]&0x0ff)<<16)
+((yytext[2]&0x0ff)<<8)
+(yytext[3]&0x0ff); return INT; }
"\'"[^\\\'][^\\\'][^\\\'][^\\\']"\'" { yylval.u_ival = ((yytext[1]&0x0ff)<<24)
+((yytext[2]&0x0ff)<<16)
+((yytext[3]&0x0ff)<<8)
+(yytext[4]&0x0ff); return INT; }
"$"?"0" { yylval.u_ival = 0;return INT;}
"$" { return DOLLAR; }
"," { return COMMA; }
/sw/zasm/asmdata.cpp
68,9 → 68,6
m_lines = new ASMLINE *[1];
m_lines[m_nlines++] = line;
}
 
if (m_lineno > line->m_lineno)
m_lineno = line->m_lineno;
};
 
bool LLINE::isdefined(void) {
204,7 → 201,6
fwrite(buf, sizeof(ZIPI), 1, m_fp);
}
} else {
fprintf(stderr, "Line %d contains an undefined symbol: ", ln->m_lineno);
fprintf(stderr, "PC = 0x%08x isn\'t ready yet\n", i->m_pc);
i->m_ln->dump(stderr);
all_reduced = false;
296,24 → 292,9
yyerror("16-bit Immediate out of range");
in = zp.op_ldilo(m_cond, imm, m_opa);
break;
case OP_MPYU:
if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC)
||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC))
yyerror("MPYU does not support PC or CC register operands or results");
else if (m_opb == zp.ZIP_Rnone)
in = zp.op_mpyu(m_cond, imm, m_opa);
else
in = zp.op_mpyu(m_cond, imm, m_opb, m_opa);
case OP_MPY:
in = zp.op_mpy(m_cond, imm, m_opb, m_opa);
break;
case OP_MPYS:
if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC)
||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC))
yyerror("MPYS does not support PC or CC register operands or results");
else if (m_opb == zp.ZIP_Rnone)
in = zp.op_mpys(m_cond, imm, m_opa);
else
in = zp.op_mpys(m_cond, imm, m_opb, m_opa);
break;
case OP_ROL:
if (m_opa == zp.ZIP_Rnone)
yyerror("ROL needs a register result");
365,7 → 346,6
LLINE *lln = new LLINE;
lln->addline(new ILINE(zp.op_ldihi(m_cond, (imm>>16)&0x0ffff, m_opa)));
lln->addline(new ILINE(zp.op_ldilo(m_cond, imm&0x0ffff, m_opa)));
lln->m_lineno = m_lineno;
return lln;
} else
in = zp.op_ldi(imm, m_opa);
376,15 → 356,6
case OP_NOT:
in = zp.op_not(m_cond, m_opb);
break;
case OP_NEG:
if (m_cond != zp.ZIPC_ALWAYS) {
yyerror("Illegal operation: Conditional negate. Negates cannot handle conditions");
} else {
LLINE *lln = new LLINE;
lln->addline(new ILINE(zp.op_not(m_opb)));
lln->addline(new ILINE(zp.op_add(1,m_opb)));
return lln;
}break;
case OP_JMP:
if (!fitsin(imm, 16))
yyerror("JMP: Immediate out of range");
447,9 → 418,7
yyerror(ebuf);
in = zp.op_noop(); break;
}
}
ILINE *rs = new ILINE(in);
rs->m_lineno = m_lineno;
} return new ILINE(in);
}
 
int TLINE::nlines(void) {
474,11 → 443,11
 
void TLINE::dump(FILE *fp) {
if (m_state == 'V')
fprintf(fp, "Void @%d\n", m_lineno);
fprintf(fp, "Void\n");
else if (m_state != 'T')
fprintf(fp, "TLINE state != T (== %c)\n", m_state);
else {
fprintf(fp, "TLINE @%d\n", m_lineno);
fprintf(fp, "TLINE\n");
switch(m_opcode) {
case OP_CMP: fprintf(fp, "\tTLINE OP = CMP\n");
break;
486,14 → 455,12
break;
case OP_MOV: fprintf(fp, "\tTLINE OP = MOV\n");
break;
case OP_LDIHI:fprintf(fp,"\tTLINE OP = LDIHI\n");
case OP_LDIHI: fprintf(fp, "\tTLINE OP = LDIHI\n");
break;
case OP_LDILO:fprintf(fp,"\tTLINE OP = LDILO\n");
case OP_LDILO: fprintf(fp, "\tTLINE OP = LDILO\n");
break;
case OP_MPYU: fprintf(fp,"\tTLINE OP = MPYU\n");
case OP_MPY: fprintf(fp, "\tTLINE OP = MPY\n");
break;
case OP_MPYS: fprintf(fp,"\tTLINE OP = MPYS\n");
break;
case OP_ROL: fprintf(fp, "\tTLINE OP = ROL\n");
break;
case OP_SUB: fprintf(fp, "\tTLINE OP = SUB\n");
537,8 → 504,6
break;
case OP_CLR: fprintf(fp, "\tTLINE OP = CLR\n");
break;
case OP_NEG: fprintf(fp, "\tTLINE OP = NEG\n");
break;
case OP_TRAP: fprintf(fp, "\tTLINE OP = TRAP\n");
break;
case OP_HALT: fprintf(fp, "\tTLINE OP = HALT\n");
/sw/zasm/asmdata.h
49,12 → 49,11
#include "zparser.h"
 
extern "C" char *linecp;
extern int yylineno;
 
typedef enum {
// TST OPCND
// Dual operand instructions that take conditions
OP_CMP, OP_TST, OP_MOV, OP_LDIHI, OP_LDILO, OP_MPYU, OP_MPYS, OP_ROL,
OP_CMP, OP_TST, OP_MOV, OP_LDIHI, OP_LDILO, OP_MPY, OP_ROL,
OP_SUB, OP_AND, OP_ADD, OP_OR, OP_XOR,
OP_LSL, OP_ASR, OP_LSR,
// Memory operands/operators
66,7 → 65,7
// Branch operands
OP_BRA, OP_BZ, OP_BNZ, OP_BGE, OP_BGT, OP_BLT, OP_BRC, OP_BRV,
// Single operand instructions that have no explicit conditions
OP_CLR, OP_TRAP, OP_NEG,
OP_CLR, OP_TRAP,
// BAREOPs that can have conditions
OP_HALT, OP_RTU, OP_BUSY,
// BAREOPs without conditions
80,7 → 79,6
class ASMLINE {
public:
char m_state;
int m_lineno;
virtual bool isdefined(void) { return true; };
virtual ~ASMLINE(void) {};
virtual int nlines(void) { return 0; }
119,7 → 117,7
class ILINE : public ASMLINE { // Instruction line
public:
ZIPI m_in;
ILINE(const ZIPI in) : m_in(in) { m_state = 'I'; m_lineno = yylineno; };
ILINE(const ZIPI in) : m_in(in) { m_state = 'I'; };
virtual bool isdefined(void) { return true; };
virtual int nlines(void) { return 1; }
virtual unsigned int eval(const int lno);
128,7 → 126,7
 
class VLINE : public ASMLINE { // Void line
public:
VLINE(void) { m_state = 'V'; m_lineno = yylineno; };
VLINE(void) { m_state = 'V'; };
virtual bool isdefined(void) { return true; };
virtual int nlines(void) { return 0; }
virtual unsigned int eval(const int lno);
138,7 → 136,7
class DLINE : public ASMLINE { // Data line
public:
ZIPI m_data;
DLINE(const ZIPI dat) : m_data(dat) { m_state = 'D'; m_lineno = yylineno; };
DLINE(const ZIPI dat) : m_data(dat) { m_state = 'D'; };
virtual bool isdefined(void) { return true; };
virtual int nlines(void) { return 1; }
virtual unsigned int eval(const int lno);
150,7 → 148,7
public:
int m_nlines;
ASMLINE **m_lines;
LLINE(void) : m_nlines(0), m_lines(NULL) { m_state = 'L'; m_lineno = yylineno; };
LLINE(void) : m_nlines(0), m_lines(NULL) { m_state = 'L'; };
void addline(ASMLINE *line) ;
virtual bool isdefined(void);
~LLINE(void);
171,7 → 169,7
 
TLINE(void) : m_opcode(OP_NONE), m_cond(ZPARSER::ZIPC_ALWAYS),
m_imm(NULL), m_opa(ZPARSER::ZIP_Rnone), m_opb(ZPARSER::ZIP_Rnone)
{ m_state = 'T'; m_lineno = yylineno; };
{ m_state = 'T'; };
virtual bool isdefined(void) {
if (m_imm != NULL) {
bool answer = m_imm->isdefined();
262,7 → 260,6
public:
OBJFILE(void) { m_fp = NULL; m_pc = 0; }
void open(const char *fname);
void close(void) { fclose(m_fp); };
unsigned int pc(void) { return m_pc; }
void operator+=(ASMLINE *ln);
bool reduce(void);
/sw/zasm/zparser.cpp
122,18 → 122,12
return in;
}
 
ZIPI ZPARSER::op_mpyu(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const {
return (0x04<<28)|((a&0x0f)<<24)|((cnd&0x7)<<21)|(0<<20)|((b&0x0f)<<16)|(imm & 0x0ffff);
} ZIPI ZPARSER::op_mpyu(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const {
return (0x04<<28)|((a&0x0f)<<24)|((cnd&0x7)<<21)|(0<<20)|((0x0f)<<16)|(imm & 0x0ffff);
ZIPI ZPARSER::op_mpy(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const {
return DBLREGOP(0x4, cnd, imm, b, a);
} ZIPI ZPARSER::op_mpy(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const {
return IMMOP(0x4, cnd, imm, a);
}
 
ZIPI ZPARSER::op_mpys(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const {
return (0x04<<28)|((a&0x0f)<<24)|((cnd&0x7)<<21)|(1<<20)|((b&0x0f)<<16)|(imm & 0x0ffff);
} ZIPI ZPARSER::op_mpys(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const {
return (0x04<<28)|((a&0x0f)<<24)|((cnd&0x7)<<21)|(1<<20)|((0x0f)<<16)|(imm & 0x0ffff);
}
 
ZIPI ZPARSER::op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const {
return DBLREGOP(0x5, cnd, imm, b, a);
} ZIPI ZPARSER::op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const {
157,10 → 151,6
ZIPI ZPARSER::op_sub(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const {
return DBLREGOP(0x8, cnd, imm, b, a);
} ZIPI ZPARSER::op_sub(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const {
// While it seems like we might do well replacing a subtract immediate
// with an add of the negative same, the conditions aren't the same
// when doing so. Hence this is an invalid substitution.
// return IMMOP(0xa, cnd, -imm, a); // Do an add of the negative of imm
return IMMOP(0x8, cnd, imm, a);
}
 
/sw/zasm/obj-pc/depends.txt
1,6 → 1,7
obj-pc/asmdata.o: asmdata.cpp asmdata.h zopcodes.h zparser.h
obj-pc/optest.o: optest.cpp zopcodes.h
obj-pc/twoc.o: twoc.cpp twoc.h
obj-pc/zasm.o: zasm.cpp zopcodes.h zparser.h
obj-pc/zdump.o: zdump.cpp zopcodes.h
obj-pc/zopcodes.o: zopcodes.cpp twoc.h zopcodes.h
obj-pc/zparser.o: zparser.cpp zparser.h zopcodes.h
/sw/zasm/zparser.h
100,20 → 100,13
ZIPI op_ldilo(ZIPIMM imm, ZIPREG a) const
{ return op_ldilo(ZIPC_ALWAYS, imm, a); }
 
ZIPI op_mpyu(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const;
ZIPI op_mpyu(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const;
ZIPI op_mpyu(ZIPIMM imm, ZIPREG b, ZIPREG a) const
{ return op_mpyu(ZIPC_ALWAYS, imm, b, a); }
ZIPI op_mpyu(ZIPIMM imm, ZIPREG a) const
{ return op_mpyu(ZIPC_ALWAYS, imm, a); }
ZIPI op_mpy(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const;
ZIPI op_mpy(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const;
ZIPI op_mpy(ZIPIMM imm, ZIPREG b, ZIPREG a) const
{ return op_mpy(ZIPC_ALWAYS, imm, b, a); }
ZIPI op_mpy(ZIPIMM imm, ZIPREG a) const
{ return op_mpy(ZIPC_ALWAYS, imm, a); }
 
ZIPI op_mpys(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const;
ZIPI op_mpys(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const;
ZIPI op_mpys(ZIPIMM imm, ZIPREG b, ZIPREG a) const
{ return op_mpys(ZIPC_ALWAYS, imm, b, a); }
ZIPI op_mpys(ZIPIMM imm, ZIPREG a) const
{ return op_mpys(ZIPC_ALWAYS, imm, a); }
 
ZIPI op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const;
ZIPI op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const;
ZIPI op_rol(ZIPIMM imm, ZIPREG b, ZIPREG a) const
/sw/zasm/Makefile
95,7 → 95,7
 
.PHONY: test
test: dumpd.txt
z.out: test.S zasm zdump zpp
z.out: test.S zasm zdump
./zasm test.S -o z.out
dumpd.txt: z.out zdump
./zdump z.out > dumpd.txt

powered by: WebSVN 2.1.0

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