main.c
9.77 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
/************************************************************************
WHAT: RSP SCALAR UNIT VERIFICATION TEST PROGRAM GENERATOR
SCCS: @(#)main.c 1.1 03 Aug 1994
PTLS: $Id: main.c,v 1.1.1.1 2002/10/29 08:07:09 blythe Exp $
FILE: main.c
ENGR: Evan Y. Wang
PROJ: Project Reality
(CR): 1994 Silicon Graphics, Inc.
************************************************************************
Files of Interest:
main.c This file.
alu_wi.c Arithmetic/logic instruction of the WI format.
alu_www.c Arithmetic/logic instruction of the WWW format.
alu_wwi.c Arithmetic/logic instruction of the WWI format.
br*.c Branch instructions.
gen.h Main header file.
j*.c Jump instructions.
ld.c Load instructions.
st.c Store instructions.
suregre.h Header file used by test programs and also generators.
table.c Instruction table and simulation subroutines.
vld.c Vector load instructions.
vlt.c Matrix transpose instructions (not yet completed).
vst.c Vector store instructions.
************************************************************************/
#include <stdio.h>
#include <string.h>
#include "software.h"
#include "gen.h"
FILE *fhSFile; /* rsp sim source file handle */
/************************************************************************
SCALAR UNIT MODEL AND TEST GENERATION VARIABLES
************************************************************************/
DATA Mem[WMEMSIZE]; /* memory model */
DATA VReg[32][4]; /* vector unit register file model */
u32 Reg[32]; /* scalar unit register file model */
u32 Res = 0; /* predicted result */
u32 OpA = 0; /* input operand A */
u32 OpB = 0; /* input operand B */
u32 Imm = 0; /* immediate operand */
int rT = 2; /* prediction reg ID */
int rA = 3; /* operand A reg ID */
int rB = 4; /* operand B reg ID */
int rR = 5; /* destination reg ID */
int CurTcNo = 1; /* current test case number */
int NxTcNo = 1; /* next test case number */
int CntA = 0; /* index used in enumerating operand A */
int CntB = 0; /* index used in enumerating operand B */
int CntI = 0; /* index used in enumerating immed op */
int vT = 0; /* target vector register ID */
int vA = 1; /* test vector register A ID */
int vB = 2; /* test vector register B ID */
int vC = 3; /* test vector register C ID */
int El; /* element field */
u16 VCC; /* VCC register (mapped to v$1) */
u16 VCO; /* VCO register (mapped to v$0) */
/************************************************************************
Lookup(..) - finds a given instruction in the instruction table and
passes back a pointer to that entry. Lookup returns TRUE if the entry
is found and the returned pointer is valid. Otherwise it returns FALSE.
************************************************************************/
PRIVATE u1 Lookup(instr, ip)
char *instr; /* instruction name to look up */
I_TABLE **ip; /* instruction table pointer variable */
{
while (*ip <= &InstrTable[InstrTableSize-1]) {
if (!strcmp(instr, (*ip)->name))
return TRUE;
else
(*ip)++;
}
return FALSE;
} /* Lookup */
/************************************************************************
Header(..) - print common test program header/comment.
************************************************************************/
PRIVATE void Header(outp, ip)
FILE *outp;
I_TABLE *ip;
{
fprintf(outp,"/****************************************************************\n");
fprintf(outp," This program tests the instruction: %s\n", ip->name);
fprintf(outp," ****************************************************************/\n\n");
fprintf(outp,"#include \"suregre.h\"\n\n");
fprintf(outp,".base 0x%8.8lX\n\n", IMEM_BASE);
} /* Header */
/************************************************************************
Init
/************************************************************************
InitModel(..) - initialize variables associated wit the model and
test generation.
************************************************************************/
PRIVATE void InitModel(outp, ip)
FILE * outp;
I_TABLE * ip;
{
int i, j;
u32 tmp;
/********************************************************************
Initialize data memory to:
********************************************************************/
switch (ip->mem) {
case NMEM:
break;
case VMEM:
case SMEM:
fprintf(outp,"\t.data\t0x%8.8lX\n", DMEM_BASE);
tmp = 0x01820384;
for (i=0; i<WMEMSIZE; i++) {
fprintf(outp,"\t.word\t0x%8.8lX\n",*WMem[i]=tmp);
tmp += 0x04040404;
tmp ^= 0x80808080;
}
fprintf(outp,"\n");
vT = 0; vA = 1; El = 0;
break;
case ZMEM:
fprintf(outp,"\t.data\t0x%8.8lX\n", DMEM_BASE);
for (i=0; i<WMEMSIZE; i++)
fprintf(outp,"\t.word\t0x%8.8lX\n",*WMem[i] = 0);
fprintf(outp,"\n");
break;
}
Reg[0] = 0;
fprintf(outp,"\tLI(r0 , 0xFFFF, 0xFFFF);\n");
for (i=1; i<32; i++) {
Reg[i] = 0x01010101 * i; /* init model reg file */
fprintf(outp,"\tLI(r%-2d, 0x%4.4X, 0x%4.4X);\n",
i, HHW(Reg[i]), LHW(Reg[i]));
}
Res = OpA = OpB = Imm = 0; /* init test operands */
rT=2; rA=3; rB=4; rR=5; /* init reg IDs */
CurTcNo = 1; /* reset current test no*/
CntA = CntB = CntI = 0;
/********************************************************************
Initialize vector registers
********************************************************************/
if (ip->mem == VMEM || ip->mem == ZMEM) {
VReg[0][0].w = VReg[0][1].w = VReg[0][2].w = VReg[0][3].w = 0;
fprintf(outp,"\tlqv v0[0], 0 (r0);\n");
for (i=0; i<32; i++) {
for (j=0; j<4; j++) VReg[i][j].w = 0;
fprintf(outp,"\tvxor v%-2d, v0, v0\n", i);
}
}
} /* InitModel */
/************************************************************************
Tail(..) - print common test end statements.
************************************************************************/
PRIVATE void Tail(outp, ip)
FILE *outp;
I_TABLE *ip;
{
fprintf(outp,"\n\tori\tr1, r0, 0xFEED;\n");
fprintf(outp,"Fail:\tbreak;\n");
} /* Tail */
/************************************************************************
FormTest(..) - form top-level test program pieces, calling a lower-
level routine to generate the test cases.
************************************************************************/
PRIVATE void FormTest(ip)
I_TABLE *ip;
{
int FileCount = 1; /* test file count per instruction */
char cTFName[20]; /* output test filename buffer */
FILE *fhTFile; /* output test file handle */
NxTcNo = 1;
while (NxTcNo != 0) { /* when NxTcNo == 0, then done */
/****************************************************************
Open output file.
****************************************************************/
sprintf(cTFName, "%s%d.s", ip->name, FileCount);
if ((fhTFile = fopen(cTFName, "w")) == NULL) {
fprintf(stderr,"ERR: Opening file %s failed.\n", cTFName);
}
fprintf(fhSFile,"load %s%d.bin 0x%8.8lX\n",ip->name,FileCount,IMEM_BASE);
fprintf(fhSFile,"load %s%d.dat 0x%8.8lX\n",ip->name,FileCount,DMEM_BASE);
fprintf(fhSFile,"dep PC 0\nrun\nreg 1\n\n");
fprintf(stderr,"Now generating %s%d.s...\n",ip->name,FileCount);
FileCount++;
/****************************************************************
Generate common header and initialization code.
****************************************************************/
Header(fhTFile, ip); /* generate file header */
InitModel(fhTFile, ip); /* init regster file model */
/****************************************************************
Generate test cases - We call the appropriate test case
generator as stored in the instruction table. We pass the
generator a pointer to the table entry so it can retrieve
additional information from the table, the NxTcNo for creating
multiple files per instruction, and, the output file handle so
the generator can write test cases directly into the test
program file.
****************************************************************/
NxTcNo = ip->gen(fhTFile, ip);
/****************************************************************
Complete each test program with ending code and close the file.
****************************************************************/
Tail(fhTFile, ip); /* generate tail */
fclose(fhTFile);
/****************************************************************
Sanity check - could use assert facility here.
****************************************************************/
if (NxTcNo > 0x1000) {
fprintf(stderr,
"WARN: Too many test cases generated to be correct!\n");
exit(1);
}
} /* while */
} /* FormTest */
/************************************************************************
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[];
{
I_TABLE *ip = &InstrTable[0]; /* instruction entry pointer */
if ((fhSFile = fopen("su.src", "w")) == NULL) {
fprintf(stderr,"ERR: Opening file rspsim.src failed.\n");
}
fprintf(fhSFile,"silent\n");
if (argc == 1) { /* generate all tests */
while (ip <= &InstrTable[InstrTableSize-1])
FormTest(ip++);
} else { /* generate selected ones */
while (argc-- > 1) {
ip = &InstrTable[0]; /* instruction entry pointer */
if (Lookup(argv[argc], &ip))
FormTest(ip);
else
printf("ERR: Could not find %s in instruction table.\n",
argv[argc]);
}
}
fprintf(fhSFile,"q\n");
fclose(fhSFile);
} /* main */