instr.c
5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/************************************************************************
WHAT: RSP SCALAR UNIT BYPASS VERIFICATION TEST PROGRAM GENERATOR
SCCS: %W% %G%
PTLS: $Id: instr.c,v 1.1.1.1 2002/05/02 03:29:13 blythe Exp $
ENGR: Evan Y. Wang
PROJ: Project Reality
(CR): 1994 Silicon Graphics, Inc.
************************************************************************/
#include <stdio.h>
#include <math.h>
#include "software.h"
#include "bpgen.h"
ITABLE I1Table[] = {
{ "\tjalr\t$%d,\t$%d\n", OP_JALR, VTYPE_UIP, 0, 0x01, 0x01 },
{ "\tcfc2\t$%d,\t$v0\n", OP_CFC2, VTYPE_U16, 0, 0x02, 0x02 },
{ "\txor\t$%d,\t$%d,\t$%d\n", OP_XOR, VTYPE_U32, 0, 0x04, 0x04 },
{ "\txori\t$%d,\t$%d,\t0xFFFF\n", OP_XORI, VTYPE_U32, 0, 0x08, 0x08 },
{ "\tlw\t$%d,\t0($%d)\n", OP_LW, VTYPE_U32, 0, 0x10, 0x10 },
};
int I1TableSize = sizeof(I1Table)/sizeof(I1Table[0]);
ITABLE I2Table[] = {
{ "\txor\t$%d,\t$%d,\t$%d\n", OP_XOR, VTYPE_U32, 0, 0xFF, 0xFF },
{ "\txori\t$%d,\t$%d,\t0xFFFF\n", OP_XORI, VTYPE_U32, 0, 0xFF, 0xFF },
{ "\tlw\t$%d,\t0($%d)\n", OP_LW, VTYPE_UDP, 0, 0xFF, 0xFF },
{ "\tbne\t$%d,\t$%d,\tFail\n", OP_BNE, VTYPE_EQU, 0, 0xFF, 0xFE },
{ "/*%d*/\tctc2\t$%d,\t$v0\n", OP_CTC2, VTYPE_U16, 0, 0xFF, 0xFF },
{ "\tlqv\t$v%d[0],\t0($%d)\n", OP_LQV, VTYPE_UDP, 0, 0xFF, 0xFF },
{ "\tjalr\t$%d,\t$%d\n", OP_JALR, VTYPE_UIP, 0, 0xFE, 0xFE },
};
int I2TableSize = sizeof(I2Table)/sizeof(I2Table[0]);
u32 InstrEmulation(outp,i1,i2,rt,r1,r2,r3,rd,tip)
FILE *outp; /* test file - use this sparingly! */
int i1; /* test instruction 1 index to I1Table */
int i2; /* test instruction 2 index to I2Table */
int rt; /* target/destination register ID */
int r1; /* source 1 register ID */
int r2; /* source 2 register ID */
int r3; /* source 3 register ID */
int rd; /* dump register ID */
u32 tip; /* PC of test instruction 1 */
{
int i;
u32 tdp,ttip;
u8 *pch;
u8 *pch2;
tip+=(2<<2); /* for initialization of Reg[r1] */
/********************************************************************
TEST INSTRUCTION 1 EMULATION
********************************************************************/
Reg[r1] = Rand32();
Reg[rd] = Rand32();
Vco = (Reg[rd] & 0xFFFF) | (Reg[rd]&0x8000 ? ~0xFFFF : 0);
/********************************************************************
TEST PREPARATION STEP 1: At this point all of the "input" registers
are initialized. However, for some special (a majority given how
we selected the instructions) cases the input registers are altered.
They are altered below in the first pass.
********************************************************************/
switch (I1Table[i1].op) {
case OP_JALR:
/* re-assign Reg[r1] value */
Reg[r1] = tip+(2<<2);
Reg[rt] = tip+(2<<2);
break;
case OP_CFC2:
/* re-assign VCO value */
if (I2Table[i2].vtype == VTYPE_UIP) Vco = tip+((Space+3)<<2);
Reg[rt] = Vco;
break;
case OP_XOR:
/* re-assign Reg[r1] value */
if (I2Table[i2].vtype == VTYPE_UIP)
Reg[r1] = (tip+((Space+3)<<2)) ^ Reg[r2];
Reg[rt] = Reg[r1] ^ Reg[r2];
break;
case OP_XORI:
/* re-assign Reg[r1] value */
if (I2Table[i2].vtype == VTYPE_UIP)
Reg[r1] = (tip+((Space+3)<<2)) ^ 0xFFFF;
Reg[rt] = Reg[r1] ^ 0xFFFF;
break;
}
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r1,Reg[r1]>>16);
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r1,Reg[r1]&0xFFFF);
/********************************************************************
TEST PREPARATION STEP 2: Second pass through test instruction 1.
We only use (and not alter) the "input" registers.
********************************************************************/
switch (I1Table[i1].op) {
case OP_LW:
tdp = (Reg[r1]&(DMEM_SIZE-1))>>2;
pch = &DMem[tdp].u.h.u.hb + (Reg[r1]&3);
if (I2Table[i2].vtype == VTYPE_UIP) {
tip += (3<<2); /* adjust Tip for following three instructions */
ttip = tip+((Space+3)<<2); /* prediction of Tip at test */
fprintf(outp,"\tlui\t$%d,\t0\n",rd);
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",rd,ttip);
fprintf(outp,"\tsw\t$%d,\t0($%d)\n",rd,r1);
*(pch) = (ttip>>24)&0xFF; *(pch+1) = (ttip>>16)&0xFF;
*(pch+2) = (ttip>> 8)&0xFF; *(pch+3) = (ttip )&0xFF;
}
Reg[rt] = *(pch)<<24 | *(pch+1)<<16 | *(pch+2)<<8 | *(pch+3);
break;
}
/********************************************************************
TEST PREPARATION STEP 3: Emulate test instruction 2.
********************************************************************/
switch (I2Table[i2].op) {
case OP_XOR:
Reg[rd] = Reg[rt] ^ Reg[r3];
break;
case OP_XORI:
Reg[rd] = Reg[rt] ^ 0xFFFF;
break;
case OP_LW:
tdp = (Reg[rt]&(DMEM_SIZE-1))>>2;
pch = &DMem[tdp].u.h.u.hb + (Reg[rt]&3);
Reg[rd] = *(pch)<<24 | *(pch+1)<<16 | *(pch+2)<<8 | *(pch+3);
break;
case OP_BNE:
Reg[rd] = Reg[rt];
break;
case OP_CTC2:
Vco = (Reg[rt] & 0xFFFF) | (Reg[rt]&0x8000 ? ~0xFFFF : 0);
break;
case OP_LQV:
/* The result of this emulation is not used. We leave it in
* in case we need in the future.
*/
tdp = Reg[rt]&(DMEM_SIZE-1);
pch = &DMem[(tdp>>4)<<2].u.h.u.hb + (tdp&0xF);
pch2 = &VReg[rd][0].u.h.u.hb;
for (i=tdp&0xF; i<0x10; i++) *pch2++ = *pch++;
break;
case OP_JALR:
Reg[rd] = tip+((Space+3)<<2);
break;
}
return tip;
} /* InstrEmulation */