bpmain.c
11.6 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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
/************************************************************************
WHAT: RSP SCALAR UNIT BYPASS VERIFICATION TEST PROGRAM GENERATOR
SCCS: %W% %G%
PTLS: $Id: bpmain.c,v 1.1.1.1 2002/05/02 03:29:12 blythe Exp $
ENGR: Evan Y. Wang
PROJ: Project Reality
(CR): 1994 Silicon Graphics, Inc.
************************************************************************/
#include <stdio.h>
#include <string.h>
#include "software.h"
#include "bpgen.h"
/************************************************************************
REGRESSION TEST GENERATOR VARIABLES.
************************************************************************/
FILE *fhSFile;
FILE *fhTFile;
char cTFName[20];
int FileCount = 0;
int TestNum = 1;
u32 Tip = IMEM_BASE;
int Space = 2;
int DestRegID = 1;
int Src1RegID = 2;
int Src2RegID = 3;
int Src3RegID = 4;
int DumpRegID = 5;
/************************************************************************
RSP STATE MODEL.
************************************************************************/
u32 Vco;
u32 Reg[32];
UD32 VReg[32][4];
UD32 DMem[DMEM_SIZE>>2]; /* 4K of DMEM */
u32 Rand32() { return rand()<<16|rand(); }
/************************************************************************
Header(..) - print common test program header/comment.
************************************************************************/
void Header(outp, tno)
FILE *outp;
int tno;
{
fprintf(outp,"/********************************");
fprintf(outp,"********************************\n");
fprintf(outp," SCALAR UNIT BYPASS TEST: %d\n", tno);
fprintf(outp," ********************************");
fprintf(outp,"********************************/\n\n");
fprintf(outp,".base 0x%8.8lX\n\n", IMEM_BASE);
} /* Header */
/************************************************************************
AddSrcEntry(..) - add to the rspsim source file.
************************************************************************/
void AddSrcEntry(outp, tfno)
FILE *outp;
int tfno;
{
fprintf(fhSFile, "load bptest%d.bin 0x%8.8lX\n",tfno,IMEM_BASE|0x04001000);
fprintf(fhSFile, "load bptest%d.dat 0x%8.8lX\n",tfno,DMEM_BASE);
fprintf(fhSFile, "dep PC 0\nrun\nreg 1\n");
} /* AddSrcEntry */
/************************************************************************
DmemInit(..) - initialize DMEM.
************************************************************************/
PRIVATE void DMemInit(outp)
FILE *outp;
{
int i;
u32 tdp;
tdp = 0;
for (i=0; i<(DMEM_SIZE>>2); i++, tdp+=4)
fprintf(outp,"\t.word\t0x%8.8lX\t\t/* Addr: 0x%4.4X */\n",
DMem[i].w=Rand32(), tdp);
} /* DMemInit */
/************************************************************************
RFileInit(..) - initialize scalar unit register file.
************************************************************************/
PRIVATE void RFileInit(outp)
FILE *outp;
{
int i;
LI(0 , 0xFFFFFFFF);
for (i=1; i<32; i++) {
LI(i, (0x01010101 * i));
}
} /* RFileInit */
/************************************************************************
Tail(..) - print common test end statements.
************************************************************************/
void Tail(outp)
FILE *outp;
{
int i;
fprintf(outp,"\n\tlui\t$1, 0xFEED;\n");
for (i=0; i<32; i++) {
fprintf(outp,"\tsw\t$%d, 0x%x($0);\n", i, 0xf80+(i*4));
}
fprintf(outp,"Fail:\tbreak;\n");
} /* Tail */
/************************************************************************
TestGen(..) - generate a test case
************************************************************************/
PRIVATE void TestGen(outp,tno,i1,i2,rt,r1,r2,r3,rd)
FILE *outp; /* test file handle */
int tno; /* test number */
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 2 register ID */
int rd; /* dump register ID */
{
int i;
fprintf(outp,"\t/* TEST #%2.2d ",tno);
fprintf(outp,"*********************************************/\n");
fprintf(outp,"\tlui\t$1, 0x%X\n\n",tno); Tip+=4;
fprintf(outp,"\t/* Initialization */\n");
/* Initialize destination register */
Reg[rt] = Rand32();
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",rt,Reg[rt]>>16); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",rt,Reg[rt]&0xFFFF); Tip+=4;
/* Clear VU destination and dump registers */
fprintf(outp,"\tvxor\t$v%d,\t$v%d,\t$v%d\n",rt,rt,rt); Tip+=4;
fprintf(outp,"\tvxor\t$v%d,\t$v%d,\t$v%d\n",rd,rd,rd); Tip+=4;
/* Initialize source 2 register */
Reg[r2] = Rand32();
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r2,Reg[r2]>>16); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r2,Reg[r2]&0xFFFF); Tip+=4;
/* Initialize source 3 register */
Reg[r3] = Rand32();
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r3,Reg[r3]>>16); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r3,Reg[r3]&0xFFFF); Tip+=4;
/********************************************************************
WARNING: Adding any instruction(s) between this warning and the
end of the TestInit procedure can easily break the generator.
Proceed with extreme care.
********************************************************************/
#define TIP_TESTINSTR 74
/* WARNING: Source 1 register initialized in InstrEmulation() */
Tip = InstrEmulation(outp, i1,i2,rt,r1,r2,r3,rd,Tip+(TIP_TESTINSTR<<2))
- (TIP_TESTINSTR<<2);
/* Initialize VCO */
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",rd,Vco>>16); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",rd,Vco&0xFFFF); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
fprintf(outp,"\tctc2\t$%d,\t$v0\n",rd); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
/* Initialize dump register */
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",rd,Reg[rd]>>16); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",rd,Reg[rd]&0xFFFF); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
fprintf(outp,"\n");
fprintf(fhTFile,"\t/* Test */\n");
fprintf(fhTFile,I1Table[i1].instr,rt,r1,r2); Tip+=4;
for (i=0; i<Space; i++) {
fprintf(outp,"\tnop\n"); Tip+=4;
}
fprintf(outp,I2Table[i2].instr,rd,rt,r3); Tip+=4;
/********************************************************************
END OF WARNING.
********************************************************************/
} /* TestInit */
/************************************************************************
ResultCheck(..).
************************************************************************/
PRIVATE void ResultCheck(outp,i1,i2,rt,r1,r2,r3,rd)
FILE *outp; /* test file handle */
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 */
{
int i;
/* buffering from the test instruction pair */
fprintf(outp,"\n");
fprintf(outp,"\t/* Result Check */\n");
fprintf(outp,"\tnop\n"); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
/* check dump register */
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r1,Reg[rd]>>16); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r1,Reg[rd]&0xFFFF); Tip+=4;
fprintf(outp,"\tbne\t$%d,\t$%d,\tFail\n",r1,rd); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
/* check target register */
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r1,Reg[rt]>>16); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r1,Reg[rt]&0xFFFF); Tip+=4;
fprintf(outp,"\tbne\t$%d,\t$%d,\tFail\n",r1,rt); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
/* check VCO */
fprintf(outp,"\tcfc2\t$%d,\t$v0\n",r1); Tip+=4;
fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r2,Vco>>16); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r2,Vco&0xFFFF); Tip+=4;
fprintf(outp,"\tbne\t$%d,\t$%d,\tFail\n",r1,r2); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
/* check VREG_1 */
if (I2Table[i2].op == OP_LQV) {
fprintf(outp,"\tlui\t$%d,\t0\n",r1); Tip+=4;
fprintf(outp,"\tori\t$%d,\t0xFF\n",r1); Tip+=4;
fprintf(outp,"\tctc2\t$0,\t$v0\n"); Tip+=4;
fprintf(outp,"\tlqv\t$v%d[0],\t0($%d)\n",rt,rt); Tip+=4;
fprintf(outp,"\tveq\t$v%d,\t$v%d,\t$v%d\n",r1,rd,rt); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
fprintf(outp,"\tcfc2\t$%d,\t$v1\n",r2); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
fprintf(outp,"\tbne\t$%d,\t$%d,\tFail\n",r1,r2); Tip+=4;
fprintf(outp,"\tnop\n"); Tip+=4;
}
fprintf(outp,"\n");
} /* ResultCheck */
/************************************************************************
main(..) - gen program entry point. Determining whether we are
generating all tests in the instruction table (see table.c) as
indicated by the absence of any command line argument or just a
selected few given on the command line. FormTest is called to
generate the test program(s) for each instruction.
************************************************************************/
void main(argc,argv)
int argc;
char *argv[];
{
int j;
int i1, i2;
if ((fhSFile = fopen("bpt.scr", "w")) == NULL) {
fprintf(stderr, "ERROR:\tOpening file bpt.scr failed.\n");
fprintf(stderr, "\tContinuing...\n");
}
fprintf(fhSFile, "silent\n");
/********************************************************************
For each instruction in table I1Table[], generate a test file.
********************************************************************/
for (i1=0; i1<I1TableSize; i1++, FileCount++) {
/* Open test file. */
sprintf(cTFName,"bptest%d.s",i1);
if ((fhTFile = fopen(cTFName, "w")) == NULL) {
fprintf(stderr, "ERROR:\tOpening file %s failed.\n", cTFName);
fprintf(stderr, "\tExiting...\n");
exit(1);
}
Header(fhTFile, FileCount); /* Print header for files */
DMemInit(fhTFile); /* Initialize DMEM */
RFileInit(fhTFile); /* Initialize SU RFile */
/* Add entry to rspsim source file for current test file. */
if (fhSFile != NULL) AddSrcEntry(fhSFile, FileCount);
/* Initialize important variables. */
Tip = IMEM_BASE;
fprintf(fhTFile,"\tlui\t$1,\t0x%4.4X\n", IMEM_BASE>>16); Tip+=4;
fprintf(fhTFile,"\tori\t$1,\t0x%4.4X\n",IMEM_BASE&0xFFFF); Tip+=4;
fprintf(fhTFile,"\tlqv\t$v0[0],\t0($1)\n"); Tip+=4;
for (j=0; j<32; j++) {
fprintf(fhTFile,"\tvnxor\t$v%d,\t$v0,\t$v0\n",j); Tip+=4;
}
/* For each instruction in table I2Table, generate a test case. */
for (i2=0; i2<I2TableSize; i2++) {
/* Eliminate incompatible instruction pairs. */
if (I1Table[i1].grpmsk & I2Table[i2].grpmsk) {
/* Vary the number of NOPs between the instruction pair. */
for (Space=2;
(Space>0
||(Space==0&&(I1Table[i1].nonseq&I2Table[i2].nonseq)))
&& Space>=I1Table[i1].min_nop; Space--) {
TestGen(fhTFile,TestNum,i1,i2,
DestRegID,Src1RegID,Src2RegID,Src3RegID,DumpRegID);
ResultCheck(fhTFile,i1,i2,
DestRegID,Src1RegID,Src2RegID,Src3RegID,DumpRegID);
TestNum++;
DestRegID = ((DestRegID+1)%31)+1;
Src1RegID = ((Src1RegID+1)%31)+1;
Src2RegID = ((Src2RegID+1)%31)+1;
Src3RegID = ((Src3RegID+1)%31)+1;
DumpRegID = ((DumpRegID+1)%31)+1;
}
}
}
Tail(fhTFile);
fclose(fhTFile);
}
bpmult(FileCount++,TestNum);
fprintf(fhSFile, "q\n");
fclose(fhSFile);
} /* main */