ilmain.c
12.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
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/************************************************************************
WHAT: RSP VECTOR UNIT INTERLOCK VERIFICATION TEST PROGRAM GENERATOR
SCCS: %W% %G%
PTLS: $Id: ilmain.c,v 1.1.1.1 2002/05/02 03:29:14 blythe Exp $
ENGR: Evan Y. Wang
PROJ: Project Reality
(CR): 1994 Silicon Graphics, Inc.
************************************************************************/
#include <stdio.h>
#include <string.h>
#include "software.h"
#include "ilgen.h"
/************************************************************************
REGRESSION TEST GENERATOR VARIABLES.
************************************************************************/
FILE *fhSFile;
FILE *fhTFile;
char cTFName[20];
int Space = 2;
int Src1RegID = 2; /* cycle through 1-15 */
int Src2RegID = 3; /* cycle through 1-15 */
int Src3RegID = 4; /* cycle through 1-15 */
int DumpRegID = 5; /* cycle through 1-15 */
int CDmpRegID = 6; /* cycle through 1-15 */
int TempRegID = 7; /* cycle through 1-15 */
int DestRegID = 16; /* Stay fixed for ltv and stv */
int CDstRegID = 24; /* Stay fixed for ltv and stv */
/************************************************************************
RSP STATE MODEL.
************************************************************************/
u32 Vco;
u32 Reg[32];
UD32 VReg[32][4];
UD32 DMem[DMEM_SIZE>>2]; /* 4K of DMEM */
u32 Rand32()
{
return (((u32) (rand()&0x3FF)<<22)
| ((u32) (rand()&0x3FF)<<12)
| ((u32) (rand()&0xFFF)));
}
/************************************************************************
Header(..) - print common test program header/comment.
************************************************************************/
PRIVATE void Header(outp,fno)
FILE *outp;
int fno;
{
fprintf(outp,"/********************************");
fprintf(outp,"********************************\n");
fprintf(outp," SCALAR UNIT INTERLOCK TEST: %d\n", fno);
fprintf(outp," ********************************");
fprintf(outp,"********************************/\n\n");
fprintf(outp,".base 0x%8.8lX\n\n", IMEM_BASE);
} /* Header */
/************************************************************************
AddSrcEntry(..) - add to the rspsim source file.
************************************************************************/
PRIVATE void AddSrcEntry(outp, tfno)
FILE *outp;
int tfno;
{
fprintf(fhSFile, "load iltest%d.bin 0x04001000\n",tfno);
fprintf(fhSFile, "load iltest%d.dat 0x04000000\n",tfno);
fprintf(fhSFile, "dep PC 0\nsilent\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.
************************************************************************/
PRIVATE 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,rct,rcd,rtmp)
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 rct; /* check rt register ID */
int rcd; /* check rd register ID */
int rtmp; /* temp register ID */
{
int i;
fprintf(outp,"\t/* TEST #%2.2d ",tno);
fprintf(outp,"*********************************************/\n");
fprintf(outp,"\t/* T#=$1 Rt=$%d R1=$%d R2=$%d R3=$%d Rd=$%d Rct=$%d Rcd=$%d Rtmp=$%d */\n",
rt, r1, r2, r3, rd, rct, rcd, rtmp);
fprintf(outp,"\tlui\t$1, 0x%X\n\n",tno);
fprintf(outp,"\t/* Initialization */\n");
/********************************************************************
Initialize SU registers
********************************************************************/
Reg[rt] = Reg[rct] = Rand32(); LI(rt,Reg[rt]);
Reg[r1] = Rand32(); LI(r1,Reg[r1]);
Reg[r2] = Rand32(); LI(r2,Reg[r2]);
Reg[r3] = Rand32() & ~0xF; LI(r3,Reg[r3]);
Reg[rd] = Reg[rcd] = Rand32(); LI(rd,Reg[rd]);
Reg[rtmp] = Rand32() & ~0xF; LI(rtmp,Reg[rtmp]);
OR(rct,rt,0);
OR(rcd,rd,0);
/********************************************************************
Initialize VU registers
********************************************************************/
LQV( rt, rtmp);
LQV( rct, rtmp);
ADDI(rtmp,rtmp,0x10);
LQV( r1, rtmp);
ADDI(rtmp,rtmp,0x10);
LQV( r2, rtmp);
ADDI(rtmp,rtmp,0x10);
LQV( r3, rtmp);
ADDI(rtmp,rtmp,0x10);
LQV( rd, rtmp);
LQV( rcd, rtmp);
if (I1Table[i1].op == OP_LTV
|| I2Table[i2].op == OP_STV) {
for (i=1; i<8; i++) {
ADDI(rtmp,rtmp,0x10);
LQV( rt+i, rtmp);
LQV( rct+i,rtmp);
}
}
Vco = Reg[r2]; CTC2(r2,0);
NOP(); NOP(); NOP();
NEWLINE();
/********************************************************************
Pre-compute answer to interlock test by running the same
instruction pair under non-interlocking circumstance. This
is basically, rt replaced by rtmp1, rd replaced rtmp2, and
NOPs inserted between the pair of test instructions.
********************************************************************/
fprintf(fhTFile,"\t/* Pre-compute answer */\n");
switch (I1Table[i1].atype) {
case ARG_VVV: fprintf(fhTFile,I1Table[i1].instr,rct,r1,r2); break;
case ARG_VR: fprintf(fhTFile,I1Table[i1].instr,rct,r1); break;
case ARG_RV: fprintf(fhTFile,I1Table[i1].instr,r1,rct); break;
case ARG_R: fprintf(fhTFile,I1Table[i1].instr,r1); break;
}
NOP(); NOP(); NOP();
if (I2Table[i2].op == OP_SQV) {
LQV(rct, r3);
} else if (I2Table[i2].op == OP_STV) {
LTV(rct, r3);
} else {
switch (I2Table[i2].atype) {
case ARG_VVV: fprintf(fhTFile,I2Table[i2].instr,rcd,rct,r3); break;
case ARG_VR: fprintf(fhTFile,I2Table[i2].instr,rct,r3); break;
case ARG_RV: fprintf(fhTFile,I2Table[i2].instr,rcd,rct); break;
case ARG_R: fprintf(fhTFile,I2Table[i2].instr,rcd); break;
}
}
NOP(); NOP(); NOP();
CFC2(rt,0); NOP();
CTC2(r2,0);
NEWLINE();
/********************************************************************
Print test instruction pair.
********************************************************************/
fprintf(fhTFile,"\t/* Test */\n");
NOP(); NOP(); NOP();
switch (I1Table[i1].atype) {
case ARG_VVV: fprintf(fhTFile,I1Table[i1].instr,rt,r1,r2); break;
case ARG_VR: fprintf(fhTFile,I1Table[i1].instr,rt,r1); break;
case ARG_RV: fprintf(fhTFile,I1Table[i1].instr,r1,rt); break;
case ARG_R: fprintf(fhTFile,I1Table[i1].instr,r1); break;
}
for (i=0; i<Space; i++)
fprintf(outp,"\tnop\n");
switch (I2Table[i2].atype) {
case ARG_VVV: fprintf(fhTFile,I2Table[i2].instr,rd,rt,r3); break;
case ARG_VR: fprintf(fhTFile,I2Table[i2].instr,rt,r3); break;
case ARG_RV: fprintf(fhTFile,I2Table[i2].instr,rd,rt); break;
case ARG_R: fprintf(fhTFile,I2Table[i2].instr,rd); break;
}
NOP(); NOP(); NOP();
NEWLINE();
} /* TestInit */
/************************************************************************
ResultCheck(..).
************************************************************************/
PRIVATE void ResultCheck(outp,i1,i2,rt,r1,r2,r3,rd,rct,rcd,rtmp)
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 rct; /* check rt register ID */
int rcd; /* check rd register ID */
int rtmp; /* temp register ID */
{
int i;
/* buffering from the test instruction pair */
fprintf(outp,"\t/* Result Check */\n");
/* check VCO */
CFC2(r1,0); NOP();
BNE(r1,rt); NOP();
CTC2(0, 0); NOP(); /* clear VCO for vector compare */
/* check scalar dump register */
BNE(rd,rcd); NOP();
/* check dump register */
Reg[r1] = 0xFF;
LI(r1,Reg[r1]);
VEQ(rtmp,rd,rcd); NOP(); NOP();
CFC2(rtmp,1); NOP();
BNE(rtmp,r1); NOP();
if ( I2Table[i2].op == OP_SQV
|| I1Table[i1].op == OP_LTV
|| I2Table[i2].op == OP_STV) {
if (I2Table[i2].op == OP_SQV) LQV( rct, r3);
if (I2Table[i2].op == OP_STV) LTV( rct, r3);
VEQ(rtmp,rt,rct); NOP(); NOP();
CFC2(rtmp,1); NOP();
BNE(rtmp,r1); NOP();
if (I1Table[i1].op == OP_LTV || I2Table[i2].op == OP_STV) {
for (i=1; i<8; i++) {
VEQ(rtmp, rt+i, rct+i); NOP(); NOP();
CFC2(rtmp,1); NOP();
BNE(rtmp,r1); NOP();
}
}
} else {
/* check target register */
VEQ(rtmp,rt,rct); NOP(); NOP();
CFC2(rtmp,1); NOP();
BNE(rtmp,r1); NOP();
}
NEWLINE();
} /* 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 i1, i2;
int FileCount = 1;
int TestNum = 1;
if ((fhSFile = fopen("ilt.scr", "w")) == NULL) {
fprintf(stderr, "ERROR:\tOpening file ilt.scr failed.\n");
fprintf(stderr, "\tContinuing...\n");
}
/********************************************************************
For each instruction in table I1Table[], generate a test file.
********************************************************************/
for (i1=0; i1<I1TableSize; i1++) {
/* For each instruction in table I2Table, generate a test case. */
for (i2=0; i2<I2TableSize; i2++) {
i1 = i1;
/* Eliminate incompatible instruction pairs. */
if (I1Table[i1].grpmsk & I2Table[i2].grpmsk) {
/* Open test file. */
sprintf(cTFName,"iltest%d.s",FileCount);
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);
/* Vary the number of NOPs between the instruction pair. */
for (Space=3; Space>=0&&Space>=I1Table[i1].min_nop; Space--) {
TestGen(fhTFile,
TestNum,
i1,
i2,
DestRegID,
Src1RegID,
Src2RegID,
Src3RegID,
DumpRegID,
CDstRegID,
CDmpRegID,
TempRegID);
ResultCheck(fhTFile,
i1,
i2,
DestRegID,
Src1RegID,
Src2RegID,
Src3RegID,
DumpRegID,
CDstRegID,
CDmpRegID,
TempRegID);
TestNum++;
Src1RegID = ((Src1RegID-2)%13)+3;
Src2RegID = ((Src2RegID-2)%13)+3;
Src3RegID = ((Src3RegID-2)%13)+3;
DumpRegID = ((DumpRegID-2)%13)+3;
CDmpRegID = ((CDmpRegID-2)%13)+3;
TempRegID = ((TempRegID-2)%13)+3;
}
Tail(fhTFile);
fclose(fhTFile);
fhTFile = NULL;
FileCount++;
}
}
}
fclose(fhSFile);
} /* main */