Slight improvement in %mov performance.
This commit is contained in:
parent
48f65cef40
commit
af6f0c800f
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: codes.h,v 1.41 2002/05/29 16:29:34 steve Exp $"
|
#ident "$Id: codes.h,v 1.42 2002/05/31 04:09:58 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ struct vvp_code_s {
|
||||||
vvp_code_fun opcode;
|
vvp_code_fun opcode;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
unsigned number;
|
unsigned long number;
|
||||||
vvp_ipoint_t iptr;
|
vvp_ipoint_t iptr;
|
||||||
vvp_cpoint_t cptr;
|
vvp_cpoint_t cptr;
|
||||||
vvp_memory_t mem;
|
vvp_memory_t mem;
|
||||||
|
|
@ -154,6 +154,9 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: codes.h,v $
|
* $Log: codes.h,v $
|
||||||
|
* Revision 1.42 2002/05/31 04:09:58 steve
|
||||||
|
* Slight improvement in %mov performance.
|
||||||
|
*
|
||||||
* Revision 1.41 2002/05/29 16:29:34 steve
|
* Revision 1.41 2002/05/29 16:29:34 steve
|
||||||
* Add %addi, which is faster to simulate.
|
* Add %addi, which is faster to simulate.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vthread.cc,v 1.75 2002/05/31 00:05:49 steve Exp $"
|
#ident "$Id: vthread.cc,v 1.76 2002/05/31 04:09:58 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vthread.h"
|
# include "vthread.h"
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
# include <limits.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
|
|
@ -1424,13 +1425,19 @@ tally:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool of_MOV_clr_(vthread_t thr, vvp_code_t cp)
|
/*
|
||||||
|
* %mov <dest>, <src>, <wid>
|
||||||
|
* This instruction is implemented by the of_MOV function
|
||||||
|
* below. However, durning runtime vvp might notice that the
|
||||||
|
* parameters have certain properties that make it possible to
|
||||||
|
* replace the of_MOV opcode with a more specific instruction that
|
||||||
|
* more directly does the job. All the of_MOV*_ functions are
|
||||||
|
* functions that of_MOV might use to replace itself.
|
||||||
|
*/
|
||||||
|
static bool of_MOV0_a_(vthread_t thr, vvp_code_t cp)
|
||||||
{
|
{
|
||||||
/* Test that the address is OK just once, then use the clear
|
if ((cp->bit_idx[0]+cp->number) > thr->nbits)
|
||||||
method that relies on the results of this test. */
|
thr_check_addr(thr, cp->bit_idx[0]+cp->number-1);
|
||||||
unsigned test_addr = cp->bit_idx[0] + cp->number - 1;
|
|
||||||
if (test_addr >= thr->nbits)
|
|
||||||
thr_check_addr(thr, test_addr);
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||||
thr_clr_bit_(thr, cp->bit_idx[0]+idx);
|
thr_clr_bit_(thr, cp->bit_idx[0]+idx);
|
||||||
|
|
@ -1438,26 +1445,69 @@ static bool of_MOV_clr_(vthread_t thr, vvp_code_t cp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool of_MOV0_b_(vthread_t thr, vvp_code_t cp)
|
||||||
|
{
|
||||||
|
if (cp->bit_idx[1] >= thr->nbits)
|
||||||
|
thr_check_addr(thr, cp->bit_idx[1]);
|
||||||
|
|
||||||
|
thr->bits[cp->bit_idx[0]] &= cp->number;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool of_MOV1XZ_(vthread_t thr, vvp_code_t cp)
|
||||||
|
{
|
||||||
|
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||||
|
thr_put_bit(thr, cp->bit_idx[0]+idx, cp->bit_idx[1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool of_MOV_(vthread_t thr, vvp_code_t cp)
|
||||||
|
{
|
||||||
|
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||||
|
thr_put_bit(thr, cp->bit_idx[0]+idx,
|
||||||
|
thr_get_bit(thr, cp->bit_idx[1]+idx));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool of_MOV(vthread_t thr, vvp_code_t cp)
|
bool of_MOV(vthread_t thr, vvp_code_t cp)
|
||||||
{
|
{
|
||||||
assert(cp->bit_idx[0] >= 4);
|
assert(cp->bit_idx[0] >= 4);
|
||||||
|
|
||||||
if (cp->bit_idx[1] >= 4) {
|
if (cp->bit_idx[1] >= 4) {
|
||||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
cp->opcode = &of_MOV_;
|
||||||
thr_put_bit(thr,
|
return cp->opcode(thr, cp);
|
||||||
cp->bit_idx[0]+idx,
|
|
||||||
thr_get_bit(thr, cp->bit_idx[1]+idx));
|
|
||||||
|
|
||||||
} else if (cp->bit_idx[1] == 0) {
|
} else if (cp->bit_idx[1] == 0) {
|
||||||
/* Detect the special case where this is really just a
|
/* Detect the special case where this is really just a
|
||||||
large clear. Rewrite the instruction to skip this
|
large clear. Rewrite the instruction to skip this
|
||||||
test next time around. */
|
test next time around, and use a precoded opcode. */
|
||||||
cp->opcode = &of_MOV_clr_;
|
|
||||||
return cp->opcode(thr, cp);
|
unsigned test_addr = cp->bit_idx[0] + cp->number - 1;
|
||||||
|
|
||||||
|
unsigned addr1 = cp->bit_idx[0] / (CPU_WORD_BITS/2);
|
||||||
|
unsigned addr2 = (test_addr) / (CPU_WORD_BITS/2);
|
||||||
|
if (addr1 == addr2) {
|
||||||
|
unsigned sh1 = cp->bit_idx[0] % (CPU_WORD_BITS/2);
|
||||||
|
unsigned sh2 = (test_addr+1) % (CPU_WORD_BITS/2);
|
||||||
|
|
||||||
|
unsigned long mask = ULONG_MAX << ((sh2 - sh1) * 2UL);
|
||||||
|
mask = (~mask) << sh1*2UL;
|
||||||
|
|
||||||
|
cp->number = ~mask;
|
||||||
|
cp->bit_idx[0] = addr1;
|
||||||
|
cp->bit_idx[1] = test_addr;
|
||||||
|
cp->opcode = &of_MOV0_b_;
|
||||||
|
return cp->opcode(thr, cp);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cp->opcode = &of_MOV0_a_;
|
||||||
|
return cp->opcode(thr, cp);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
cp->opcode = &of_MOV1XZ_;
|
||||||
thr_put_bit(thr, cp->bit_idx[0]+idx, cp->bit_idx[1]);
|
return cp->opcode(thr, cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -2015,6 +2065,9 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vthread.cc,v $
|
* $Log: vthread.cc,v $
|
||||||
|
* Revision 1.76 2002/05/31 04:09:58 steve
|
||||||
|
* Slight improvement in %mov performance.
|
||||||
|
*
|
||||||
* Revision 1.75 2002/05/31 00:05:49 steve
|
* Revision 1.75 2002/05/31 00:05:49 steve
|
||||||
* Word oriented bit storage.
|
* Word oriented bit storage.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue