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 25 to Rev 26
    Reverse comparison

Rev 25 → Rev 26

/sw/zipdbg/README
0,0 → 1,12
 
This directory contains the Zip System Debugger. If you wish to use it,
you'll need to define something that implements the DEVBUS interface,
as found in devbus.h. Basically, the debugger expects to interact with the
Zip System across a 32-bit bus. Since this interaction is hardware system
specific, the implementation for your system isn't provided here.
 
Contact me if you need help building such a capability for your system.
My current implementation transforms a UART signal into 32-bit wishbone
bus interactions which then support this CPU.
 
 
/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,6 → 58,7
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
75,6 → 76,14
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
85,6 → 94,7
bra continue_test_with_testable_instructions
break
wait
break
busy
rtu
continue_test_with_testable_instructions:
206,43 → 216,52
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
#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
asr 32,r0
cmp -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
ldi -1,r0
asr 0,r0
bc test_failure
cmp -1,r0
bnz test_failure
asr 1,r0
tst sys.ccc,r14
#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
asr 30,r0
tst sys.ccc,r14
bz test_failure
#endif
 
#ifdef NOONE // Testing comments after ifdef
#else ; After else
#endif /* and after endif */
testbench:
// Let's build a software test bench.
ldi $c0000000h,r12 ; Set R12 to point to our peripheral address
252,7 → 271,7
sto r0,(r12)
rtu
mov ucc,r0
tst -256,r0
cmp sys.cctrap,r0
bnz test_failure
halt
// Go into an infinite loop if the trap fails
269,7 → 288,7
test_data:
.dat __here__+0x0100000+5
test_start:
ldi $0x0100,r11
ldi $0x01000,r11
lod test_data+pc,pc
clr r11
noop
278,8 → 297,9
add $1,r0
add $1,r0
 
#ifdef OVERFLOW_TEST
// Let's test whether overflow works
ldi $0x0200,r11
ldi $0x02000,r11
ldi $-1,r0
lsr $1,r0
add $1,r0
287,7 → 307,7
trap r11
first_overflow_passes:
// Overflow set from subtraction
ldi $0x0300,r11
ldi $0x03000,r11
ldi $1,r0
rol $31,r0 ; rol $31,r0
sub $1,r0
295,7 → 315,7
trap r11
subtraction_overflow_passes:
// Overflow set from LSR
ldi $0x0400,r11
ldi $0x04000,r11
ldi $1,r0
rol $31,r0 ; rol $31,r0
lsr $1,r0
303,7 → 323,7
trap r11
lsr_overflow_passes:
// Overflow set from LSL
ldi $0x0500,r11
ldi $0x05000,r11
ldi $1,r0
rol $30,r0
lsl $1,r0
311,28 → 331,34
trap r11
lsl_overflow_passes:
// Overflow set from LSL, negative to positive
ldi $0x0600,r11
ldi $0x06000,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 $0x0700,r11
ldi $0x07000,r11
ldi $-1,r0
add $1,r0
tst $2,cc
trap.z r11
// and carry from subtraction
ldi $0x0800,r11
ldi $0x08000,r11
clr r0
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 $0x0800,r11
ldi $0x09000,r11
clr r0
for_loop:
noop
346,7 → 372,7
// R0 = 5; (from before)
// do {
// } while (R0 > 0);
ldi $0x0900,r11
ldi $0x0a000,r11
bgt_loop:
noop
sub $1,r0
368,7 → 394,7
// R0 = 5; (from before)
// do {
// } while (R0 > 0);
ldi $0x0a00,r11
ldi $0x0b000,r11
bra mem_loop_test
loop_var:
.dat 0
386,9 → 412,44
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
399,7 → 460,40
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/zasm.y
40,6 → 40,9
#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;
75,6 → 78,13
%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:
402,6 → 412,7
 
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <assert.h>
413,9 → 424,8
if (linecp) fprintf(stderr, "Offending line was: %s\n", linecp);
}
 
FILE *run_preprocessor(const char *path = NULL, const char *zname = NULL) {
FILE *run_preprocessor(pid_t &pid, const char *path = NULL, const char *zname = NULL) {
int pipefd[2];
int pid;
 
if (pipe(pipefd)!=0) {
fprintf(stderr, "PIPE FAILED!\n");
467,11 → 477,26
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
493,16 → 518,35
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 = "z.out";
zout_fname = DEFAULT_OUTPUT_FNAME;
 
objcode.open(zout_fname);
}
520,14 → 564,16
free(master_input_filename);
master_input_filename = strdup(argv[argn]);
if (preprocess_only) {
FILE *fp = run_preprocessor(path_to_zasm, master_input_filename);
FILE *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
int ch;
while(EOF != (ch = fgetc(fp)))
fputc(ch, stdout);
fputc(ch, ppout);
waitpid(zpp_pid, &zpp_status, WNOHANG);
} else {
yyrestart(run_preprocessor(path_to_zasm, master_input_filename));
yyrestart(run_preprocessor(zpp_pid, path_to_zasm, master_input_filename));
yylineno = 1;
yyparse();
waitpid(zpp_pid, &zpp_status, WNOHANG);
}
}
} else { // Run from Stdin
538,17 → 584,24
master_input_filename = strdup("(stdin)");
if (preprocess_only) {
int ch;
FILE *fp = run_preprocessor(path_to_zasm, master_input_filename);
FILE *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
while(EOF != (ch = fgetc(fp)))
fputc(ch, stdout);
fputc(ch, ppout);
waitpid(zpp_pid, &zpp_status, WNOHANG);
} else {
yyin = run_preprocessor(NULL);
yyin = run_preprocessor(zpp_pid, NULL);
yyrestart(yyin);
yyparse();
waitpid(zpp_pid, &zpp_status, WNOHANG);
}
}
 
if (!objcode.reduce())
if (0 != WEXITSTATUS(zpp_status)) {
if (!preprocess_only) {
objcode.close();
unlink(zout_fname);
}
} if (!objcode.reduce())
fprintf(stderr, "Not all symbols defined!\n");
}
 
/sw/zasm/asmdata.cpp
68,6 → 68,9
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) {
201,6 → 204,7
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;
292,9 → 296,24
yyerror("16-bit Immediate out of range");
in = zp.op_ldilo(m_cond, imm, m_opa);
break;
case OP_MPY:
in = zp.op_mpy(m_cond, imm, m_opb, m_opa);
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);
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");
346,6 → 365,7
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);
356,6 → 376,15
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");
418,7 → 447,9
yyerror(ebuf);
in = zp.op_noop(); break;
}
} return new ILINE(in);
}
ILINE *rs = new ILINE(in);
rs->m_lineno = m_lineno;
}
 
int TLINE::nlines(void) {
443,11 → 474,11
 
void TLINE::dump(FILE *fp) {
if (m_state == 'V')
fprintf(fp, "Void\n");
fprintf(fp, "Void @%d\n", m_lineno);
else if (m_state != 'T')
fprintf(fp, "TLINE state != T (== %c)\n", m_state);
else {
fprintf(fp, "TLINE\n");
fprintf(fp, "TLINE @%d\n", m_lineno);
switch(m_opcode) {
case OP_CMP: fprintf(fp, "\tTLINE OP = CMP\n");
break;
455,12 → 486,14
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_MPY: fprintf(fp, "\tTLINE OP = MPY\n");
case OP_MPYU: fprintf(fp,"\tTLINE OP = MPYU\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");
504,6 → 537,8
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,11 → 49,12
#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_MPY, OP_ROL,
OP_CMP, OP_TST, OP_MOV, OP_LDIHI, OP_LDILO, OP_MPYU, OP_MPYS, OP_ROL,
OP_SUB, OP_AND, OP_ADD, OP_OR, OP_XOR,
OP_LSL, OP_ASR, OP_LSR,
// Memory operands/operators
65,7 → 66,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_CLR, OP_TRAP, OP_NEG,
// BAREOPs that can have conditions
OP_HALT, OP_RTU, OP_BUSY,
// BAREOPs without conditions
79,6 → 80,7
class ASMLINE {
public:
char m_state;
int m_lineno;
virtual bool isdefined(void) { return true; };
virtual ~ASMLINE(void) {};
virtual int nlines(void) { return 0; }
117,7 → 119,7
class ILINE : public ASMLINE { // Instruction line
public:
ZIPI m_in;
ILINE(const ZIPI in) : m_in(in) { m_state = 'I'; };
ILINE(const ZIPI in) : m_in(in) { m_state = 'I'; m_lineno = yylineno; };
virtual bool isdefined(void) { return true; };
virtual int nlines(void) { return 1; }
virtual unsigned int eval(const int lno);
126,7 → 128,7
 
class VLINE : public ASMLINE { // Void line
public:
VLINE(void) { m_state = 'V'; };
VLINE(void) { m_state = 'V'; m_lineno = yylineno; };
virtual bool isdefined(void) { return true; };
virtual int nlines(void) { return 0; }
virtual unsigned int eval(const int lno);
136,7 → 138,7
class DLINE : public ASMLINE { // Data line
public:
ZIPI m_data;
DLINE(const ZIPI dat) : m_data(dat) { m_state = 'D'; };
DLINE(const ZIPI dat) : m_data(dat) { m_state = 'D'; m_lineno = yylineno; };
virtual bool isdefined(void) { return true; };
virtual int nlines(void) { return 1; }
virtual unsigned int eval(const int lno);
148,7 → 150,7
public:
int m_nlines;
ASMLINE **m_lines;
LLINE(void) : m_nlines(0), m_lines(NULL) { m_state = 'L'; };
LLINE(void) : m_nlines(0), m_lines(NULL) { m_state = 'L'; m_lineno = yylineno; };
void addline(ASMLINE *line) ;
virtual bool isdefined(void);
~LLINE(void);
169,7 → 171,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_state = 'T'; m_lineno = yylineno; };
virtual bool isdefined(void) {
if (m_imm != NULL) {
bool answer = m_imm->isdefined();
260,6 → 262,7
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/zpp.l
137,11 → 137,12
<INNOTDEF>^"#else"[ \t]*((;|"//").*)?$ { BEGIN INDEF; }
<INNOTDEF>(.*) { }
<INDEF>^"#elsif"[ \t]* { BEGIN NVRDEF; }
<NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*((;|"//").*)?$ { yy_pop_state(); }
<NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*"/*" { BEGIN COMMENT; }
<NVRDEF,NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*((;|"//").*)?$ { yy_pop_state(); }
<NVRDEF,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);
}
160,11 → 161,20
}
<*>[ \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]); } */
<<EOF>> { if (end_of_file()) yyterminate(); }
<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(); }
 
%%
 
387,6 → 397,12
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)
401,7 → 417,9
const char *last_marked_file = NULL;
void mark_line(void) {
if ((yylineno != last_marked_line+1)||(BUFSTACK::curfilename != last_marked_file))
BUFSTACK::curbs->mark();
if (BUFSTACK::curfilename == last_marked_file)
BUFSTACK::curbs->markline();
else BUFSTACK::curbs->mark();
last_marked_line = yylineno;
last_marked_file = BUFSTACK::curfilename;
}
428,5 → 446,7
// delete bs;
}
}
 
return 0;
}
 
/sw/zasm/zasm.l
51,7 → 51,12
 
%%
 
^"#line"[ \t]+[0-9]+[ \t]+[\"][^"]*[\"][ \t]*$ {
"#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.
*/
yylineno = atoi(&yytext[6]);
char *bg, *en;
bg = strchr(yytext, '\"')+1;
61,8 → 66,11
master_input_filename = new char[en-bg+2];
strcpy(master_input_filename, bg);
}
return '\n';
}
^"#line"[ \t]+[0-9]+[ \t]+$ { yylineno = atoi(&yytext[6]); }
"#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'; }
[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; }
69,15 → 77,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; }
[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; }
(?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; }
[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; }
92,42 → 100,44
[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; }
[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; }
(?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; }
[lL][jJ][mM][pP] {yylval.u_op = OP_LJMP;return SINGLOP; }
[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; }
(?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; }
[lL][dD][iI][hH][iI] { yylval.u_op =OP_LDIHI; return LDHLOP; }
[lL][dD][iI][lL][oO] { yylval.u_op =OP_LDILO; return LDHLOP; }
[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; }
(?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; }
"__"[hH][eE][rR][eE]"__" { return HERE; }
[\.][dD][aA][tT] { return WORD; }
[\.][zZ]/[ \t\n] { yylval.u_cond = ZPARSER::ZIPC_Z; return COND; }
145,6 → 155,27
"$"?[-]?[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/zopcodes.cpp
131,8 → 131,10
"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),
//
"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),
"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),
//
"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/zparser.cpp
122,12 → 122,18
return in;
}
 
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_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_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 {
151,6 → 157,10
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,7 → 1,6
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,13 → 100,20
ZIPI op_ldilo(ZIPIMM imm, ZIPREG a) const
{ return op_ldilo(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_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_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
z.out: test.S zasm zdump zpp
./zasm test.S -o z.out
dumpd.txt: z.out zdump
./zdump z.out > dumpd.txt

powered by: WebSVN 2.1.0

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