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 142 to Rev 143
- ↔ Reverse comparison
Rev 142 → Rev 143
/zasm/test.S
84,7 → 84,13
#define LOOP_TEST |
#define SHIFT_TEST |
#define TRAP_TEST |
#define MPY_TEST |
; |
; Since updating our multiplies, the old MPY_TEST doesn't work anymore. It |
; really needs to be rebuilt. For now, we just disable it. I know, this is the |
; wrong approach. Test first and don't get surprised later. Yes. I need to |
; come back to this--hopefully before getting surprised. |
; |
; #define MPY_TEST |
#define PUSH_TEST |
#define PIPELINE_STACK_TEST |
#define MEM_PIPELINE_TEST |
146,7 → 152,7
ldi 0x0dead,r5 |
ldi 0x0beef,r6 |
ldi 0xdeadbeef,r7 |
ldihi 0xdead, r8 |
brev 0xb57b, r8 |
ldilo 0xbeef, r8 |
ldi dead_beef,r9 |
cmp r5,r6 |
/zasm/asmdata.cpp
40,6 → 40,7
#include <assert.h> |
#include <string.h> |
#include "asmdata.h" |
#include "twoc.h" |
|
extern void yyerror(const char *str); |
|
276,6 → 277,11
yyerror("Immediate overflow on move"); |
in = zp.op_mov(m_cond, imm, m_opb, m_opa); |
break; |
#ifdef LONG_MPY |
case OP_MPY: |
BLD_DUALOP(op_mpy); |
break; |
#else |
case OP_LDIHI: |
if ((imm & (-1<<16))!=0) |
yyerror("16-bit Immediate out of range"); |
285,6 → 291,7
yyerror("LDIHI needs a register result"); |
in = zp.op_ldihi(m_cond, imm, m_opa); |
break; |
#endif |
case OP_LDILO: |
if ((imm & (-1<<16))!=0) |
yyerror("16-bit Immediate out of range"); |
296,6 → 303,14
yyerror("16-bit Immediate out of range"); |
in = zp.op_ldilo(m_cond, imm, m_opa); |
break; |
#ifdef LONG_MPY |
case OP_MPYUHI: |
BLD_DUALOP(op_mpyuhi); |
break; |
case OP_MPYSHI: |
BLD_DUALOP(op_mpyshi); |
break; |
#else |
case OP_MPYU: |
if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC) |
||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC)) |
314,6 → 329,7
else |
in = zp.op_mpys(m_cond, imm, m_opb, m_opa); |
break; |
#endif |
case OP_ROL: |
if (m_opa == zp.ZIP_Rnone) |
yyerror("ROL needs a register result"); |
365,11 → 381,18
BLD_DUALOP(op_popc); |
break; |
case OP_LDI: |
if ((!fitsin(imm, 23))||(m_cond != zp.ZIPC_ALWAYS)) { |
if (fitsin(zp.brev(imm),18)) { |
imm = zp.brev(imm); |
BLD_DUALOP(op_brev); |
} else if ((!fitsin(imm, 23))||(m_cond != zp.ZIPC_ALWAYS)) { |
if (m_opa == zp.ZIP_PC) |
yyerror("Cannot LDI 32-bit addresses into PC register!"); |
LLINE *lln = new LLINE; |
#ifdef LONG_MPY |
lln->addline(new ILINE(zp.op_brev(m_cond, sbits(zp.brev(imm),18), m_opa))); |
#else |
lln->addline(new ILINE(zp.op_ldihi(m_cond, (imm>>16)&0x0ffff, m_opa))); |
#endif |
lln->addline(new ILINE(zp.op_ldilo(m_cond, imm&0x0ffff, m_opa))); |
lln->m_lineno = m_lineno; |
return lln; |
461,33 → 484,6
in = zp.op_lod(m_cond, imm, m_opb, m_opa); |
in = zp.op_lod(m_cond, -1, zp.ZIP_SP, zp.ZIP_PC); |
break; |
case OP_MPY: |
if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC) |
||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC)) |
yyerror("MPY does not support PC or CC register operands or results"); |
else if (m_opb == zp.ZIP_Rnone) |
in = zp.op_mpy(m_cond, imm, m_opa); |
else |
in = zp.op_mpy(m_cond, imm, m_opb, m_opa); |
break; |
case OP_MPYUHI: |
if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC) |
||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC)) |
yyerror("MPY does not support PC or CC register operands or results"); |
else if (m_opb == zp.ZIP_Rnone) |
in = zp.op_mpyuhi(m_cond, imm, m_opa); |
else |
in = zp.op_mpyuhi(m_cond, imm, m_opb, m_opa); |
break; |
case OP_MPYSHI: |
if ((m_opb == zp.ZIP_PC)||(m_opb == zp.ZIP_CC) |
||(m_opa == zp.ZIP_PC)||(m_opa == zp.ZIP_CC)) |
yyerror("MPY does not support PC or CC register operands or results"); |
else if (m_opb == zp.ZIP_Rnone) |
in = zp.op_mpyshi(m_cond, imm, m_opa); |
else |
in = zp.op_mpyshi(m_cond, imm, m_opb, m_opa); |
break; |
case OP_HALT: in = zp.op_halt(m_cond); break; |
case OP_RTU: in = zp.op_rtu(m_cond); break; |
case OP_BUSY: in = zp.op_busy(m_cond); break; |
539,14 → 535,26
break; |
case OP_MOV: fprintf(fp, "\tTLINE OP = MOV\n"); |
break; |
#ifdef LONG_MPY |
case OP_MPY: fprintf(fp,"\tTLINE OP = MPY\n"); |
break; |
#else |
case OP_LDIHI:fprintf(fp,"\tTLINE OP = LDIHI\n"); |
break; |
#endif |
case OP_LDILO:fprintf(fp,"\tTLINE OP = LDILO\n"); |
break; |
#ifdef LONG_MPY |
case OP_MPYUHI: fprintf(fp,"\tTLINE OP = MPYUHI\n"); |
break; |
case OP_MPYSHI: fprintf(fp,"\tTLINE OP = MPYSHI\n"); |
break; |
#else |
case OP_MPYU: fprintf(fp,"\tTLINE OP = MPYU\n"); |
break; |
case OP_MPYS: fprintf(fp,"\tTLINE OP = MPYS\n"); |
break; |
#endif |
case OP_ROL: fprintf(fp, "\tTLINE OP = ROL\n"); |
break; |
case OP_SUB: fprintf(fp, "\tTLINE OP = SUB\n"); |
/zasm/zparser.cpp
51,8 → 51,6
#include "zparser.h" |
#include "zopcodes.h" |
|
typedef ZPARSER::ZIPI ZIPI; // A Zip Instruction (i.e. uint32) |
|
#define IMMOP(OP,CND,IMM,A) (((OP&0x01f)<<22)|((A&0x0f)<<27)|((CND&0x07)<<19) \ |
| (IMM & 0x03ffff)) |
|
134,9 → 132,6
return DBLREGOP(ZIPO_MPY, cnd, imm, b, a); |
} ZIPI ZPARSER::op_mpy(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { |
return IMMOP(ZIPO_MPY, cnd, imm, a); |
} ZIPI ZPARSER::op_ldihi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { |
ZIPI in = IMMOP(ZIPO_BREV, cnd, brev(imm)&0x0ffff, a); |
return in; |
} |
#else |
ZIPI ZPARSER::op_ldihi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { |
149,6 → 144,19
return in; |
} |
|
#ifdef LONG_MPY |
ZIPI ZPARSER::op_mpyuhi(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { |
return DBLREGOP(ZIPO_MPYUHI, cnd, imm, b, a); |
} ZIPI ZPARSER::op_mpyuhi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { |
return IMMOP(ZIPO_MPYUHI, cnd, imm & 0x0ffff, a); |
} |
|
ZIPI ZPARSER::op_mpyshi(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { |
return DBLREGOP(ZIPO_MPYSHI, cnd, imm, b, a); |
} ZIPI ZPARSER::op_mpyshi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { |
return IMMOP(ZIPO_MPYSHI, cnd, imm & 0x0ffff, a); |
} |
#else |
ZIPI ZPARSER::op_mpyu(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { |
return DBLREGOP(ZIPO_MPYU, cnd, imm, b, a); |
} ZIPI ZPARSER::op_mpyu(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { |
160,6 → 168,7
} ZIPI ZPARSER::op_mpys(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { |
return IMMOP(ZIPO_MPYS, cnd, imm & 0x0ffff, a); |
} |
#endif |
|
ZIPI ZPARSER::op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { |
return DBLREGOP(ZIPO_ROL, cnd, imm, b, a); |
271,7 → 280,10
imm = (a & 0x03fffff); break; |
case ZIPO_LDIn: |
imm = (a & 0x03fffff); imm |= -0x200000; break; |
case ZIPO_LDILO: case ZIPO_LDIHI: |
case ZIPO_LDILO: |
#ifndef LONG_MPY |
case ZIPO_LDIHI: |
#endif |
imm = (a & 0x0ffff); break; |
default: |
if (a & 0x040000) { |
325,7 → 337,10
case ZIPO_MOV: |
imma = (a & 0x03fff); if (a) return false; break; |
case ZIPO_LDI: case ZIPO_LDIn: |
case ZIPO_LDILO: case ZIPO_LDIHI: |
case ZIPO_LDILO: |
#ifndef LONG_MPY |
case ZIPO_LDIHI: |
#endif |
imma = immediate(a); break; |
default: |
if (a & 0x040000) { |
342,7 → 357,10
case ZIPO_MOV: |
immb = (b & 0x0fff); if (b) return false; break; |
case ZIPO_LDI: case ZIPO_LDIn: |
case ZIPO_LDILO: case ZIPO_LDIHI: |
case ZIPO_LDILO: |
#ifndef LONG_MPY |
case ZIPO_LDIHI: |
#endif |
immb = immediate(b); break; |
default: |
if (b & 0x040000) { |
357,12 → 375,20
} |
} |
|
if ((opa == ZIPO_LDI)||(opa == ZIPO_LDIn)||(opa == ZIPO_LDILO)||(opa == ZIPO_LDIHI)) { |
if ((opa == ZIPO_LDI)||(opa == ZIPO_LDIn) |
#ifndef LONG_MPY |
||(opa == ZIPO_LDIHI) |
#endif |
||(opa == ZIPO_LDILO)) { |
if ((imma > 15)||(imma < -16)) |
return false; |
} else if ((imma > 7)||(imma < -8)) |
return false; |
if ((opb == ZIPO_LDI)||(opb == ZIPO_LDIn)||(opb == ZIPO_LDILO)||(opb == ZIPO_LDIHI)) { |
if ((opb == ZIPO_LDI)||(opb == ZIPO_LDIn) |
#ifndef LONG_MPY |
||(opb == ZIPO_LDIHI) |
#endif |
||(opb == ZIPO_LDILO)) { |
if ((immb > 15)||(immb < -16)) |
return false; |
} else if ((immb > 7)||(immb < -8)) |
402,7 → 428,10
switch(opa) { |
case ZIPO_MOV: ni |= (a&0x078000); break; // Always a register |
case ZIPO_LDI: case ZIPO_LDIn: |
case ZIPO_LDILO: case ZIPO_LDIHI: |
case ZIPO_LDILO: |
#ifndef LONG_MPY |
case ZIPO_LDIHI: |
#endif |
ni |= (imma & 0x01f)<<14; |
break; |
default: |
416,7 → 445,10
case ZIPO_MOV: |
ni |= ((b>>14)&0x0f)|0x10; break; |
case ZIPO_LDI: case ZIPO_LDIn: |
case ZIPO_LDILO: case ZIPO_LDIHI: |
case ZIPO_LDILO: |
#ifndef LONG_MPY |
case ZIPO_LDIHI: |
#endif |
ni |= (immb & 0x01f); |
break; |
default: |
/zasm/zparser.h
44,9 → 44,28
#ifndef ZPARSER_H |
#define ZPARSER_H |
|
/* |
* LONG_MPY controls whether or not the instruction set has: |
* (if not defined) |
* LDIHI - load the value into the upper 16 bits of a register |
* MPYS - Multiplies two 16-bit values into a signed 32-bit result |
* MPYU - Multiplies two 16-bit values into an unsigned 32-bit result |
* (if defined) |
* MPY - Multiplies two 32-bit values and returns the lower 32-bits of |
* the result. Works for signed and unsigned values. |
* MPYSHI - Multiplies two 32-bit values and returns the upper 32-bits of |
* the signed 64-bit result |
* MPYUHI - Multiplies two 32-bit values and returns the upper 32-bits of |
* the unsigned 64-bit result |
* |
*/ |
#define LONG_MPY |
|
#include "zopcodes.h" |
|
class ZPARSER { |
public: |
typedef unsigned int ZIPI, ZIPA; |
typedef unsigned int ZIPA; |
typedef int ZIPIMM; |
typedef enum { |
ZIP_R0, ZIP_R1, ZIP_R2, ZIP_R3, ZIP_R4, ZIP_R5, ZIP_R6, ZIP_R7, |
67,7 → 86,11
// 16 ALU instructions |
ZIPO_SUB=0, ZIPO_AND, ZIPO_ADD, ZIPO_OR, // 5'h000xx |
ZIPO_XOR, ZIPO_LSR, ZIPO_LSL, ZIPO_ASR, // 5'h001xx |
#ifdef LONG_MPY |
ZIPO_MPY, ZIPO_LDILO, ZIPO_MPYUHI, ZIPO_MPYSHI, // 5'h010xx |
#else |
ZIPO_LDIHI, ZIPO_LDILO, ZIPO_MPYU, ZIPO_MPYS, // 5'h010xx |
#endif |
ZIPO_BREV, ZIPO_POPC, ZIPO_ROL, ZIPO_MOV, // 5'h011xx |
ZIPO_CMP, ZIPO_TST, // 5'h1000x |
ZIPO_LOD, ZIPO_STO, // 5'h1001w |
79,10 → 102,6
ZIPO_FPCVT, ZIPO_FPINT, // 5'h1110x |
} ZIPOP; |
|
#define ZIPO_MPY ZIPO_LDIHI |
#define ZIPO_MPYSHI ZIPO_MPYS |
#define ZIPO_MPYUHI ZIPO_MPYU |
|
ZIPIMM brev(ZIPIMM) const; |
|
ZIPI op_cmp(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const; |
115,16 → 134,30
ZIPI op_break(void) const; |
ZIPI op_lock(void) const; |
|
#ifdef LONG_MPY |
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(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, 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); } |
#else |
ZIPI op_ldihi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const; |
ZIPI op_ldihi(ZIPIMM imm, ZIPREG a) const |
{ return op_ldihi(ZIPC_ALWAYS, imm, a); } |
#endif |
ZIPI op_ldilo(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const; |
ZIPI op_ldilo(ZIPIMM imm, ZIPREG a) const |
{ return op_ldilo(ZIPC_ALWAYS, imm, a); } |
|
#ifdef LONG_MPY |
ZIPI op_mpyuhi(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const; |
ZIPI op_mpyuhi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const; |
ZIPI op_mpyuhi(ZIPIMM imm, ZIPREG b, ZIPREG a) const |
{ return op_mpyuhi(ZIPC_ALWAYS, imm, b, a); } |
ZIPI op_mpyuhi(ZIPIMM imm, ZIPREG a) const |
{ return op_mpyuhi(ZIPC_ALWAYS,imm,a); } |
#else |
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 |
131,12 → 164,17
{ return op_mpyu(ZIPC_ALWAYS, imm, b, a); } |
ZIPI op_mpyu(ZIPIMM imm, ZIPREG a) const |
{ return op_mpyu(ZIPC_ALWAYS, imm, a); } |
#endif |
// |
ZIPI op_mpyuhi(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const |
{ return op_mpyu(cnd,imm,b,a); } |
ZIPI op_mpyuhi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const |
{ return op_mpyu(cnd,imm,a); } |
|
#ifdef LONG_MPY |
ZIPI op_mpyshi(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const; |
ZIPI op_mpyshi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const; |
ZIPI op_mpyshi(ZIPIMM imm, ZIPREG b, ZIPREG a) const |
{ return op_mpyshi(ZIPC_ALWAYS, imm, b, a); } |
ZIPI op_mpyshi(ZIPIMM imm, ZIPREG a) const |
{ return op_mpyshi(ZIPC_ALWAYS, imm, a); } |
#else |
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 |
143,11 → 181,7
{ 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_mpyshi(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const |
{ return op_mpys(cnd,imm,b,a); } |
ZIPI op_mpyshi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const |
{ return op_mpys(cnd,imm,a); } |
#endif |
|
ZIPI op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const; |
ZIPI op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const; |