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 142 to Rev 143
    Reverse comparison

Rev 142 → Rev 143

/sw/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
/sw/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");
/sw/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:
/sw/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;

powered by: WebSVN 2.1.0

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