blob: 9fc9a255769bf9d14df6ec963ac8f179a87ff75b [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* vsc - portable instruction scheduler for vbcc. */
2/* (c) 1997-99 by Volker Barthelmann. */
3
4#include "vsc.h"
5
6char vs_copyright[]="vsc scheduler V0.1 (c) 1997-99 by Volker Barthelmann";
7
8#define MAX_INS 128
9#define LINELENGTH 1024
10
11#ifndef DEBUG
12int DEBUG;
13#endif
14
15struct sinfo silist[MAX_INS];
16int si_count;
17int done;
18
19int bvcmp(unsigned char *dest,unsigned char *src,size_t len)
20/* vergleicht zwei Bitvektoren */
21{
22 for(;len>0;len--)
23 if(*dest++!=*src++) return(0);
24 return(1);
25}
26void bvunite(unsigned char *dest,unsigned char *src,size_t len)
27/* berechnet Vereinigung zweier Bitvektoren */
28{
29 for(;len>0;len--)
30 *dest++|=*src++;
31}
32void bvintersect(unsigned char *dest,unsigned char *src,size_t len)
33/* berechnet Durchschnitt zweier Bitvektoren */
34{
35 for(;len>0;len--)
36 *dest++&=*src++;
37}
38void bvdiff(unsigned char *dest,unsigned char *src,size_t len)
39/* berechnet 'Differenz' zweier Bitvektoren */
40{
41 for(;len>0;len--)
42 *dest++&=~(*src++);
43}
44
45void raus(void)
46{
47 sched_cleanup();
48 if(DEBUG&1) printf("raus\n");
49 if(done)
50 exit(EXIT_SUCCESS);
51 else
52 exit(EXIT_FAILURE);
53}
54void *mymalloc(size_t sz)
55{
56 void *p=malloc(sz);
57 if(!p){
58 puts("Out of memory!");
59 raus();
60 }
61 return p;
62}
63void print_sinfo(void)
64{
65 struct sinfo *p;int i,j;
66 if(DEBUG&2)
67 printf("print_sinfo\n");
68 else
69 return;
70 for(j=0;j<si_count;j++){
71 p=&silist[j];
72 printf("inst: %s",p->txt);
73 printf("flags=%u, label=%u latency=%u\n",p->flags,p->label,p->latency);
74 printf("available pipelines: ");
75 for(i=0;i<PIPES;i++)
76 if(BTST(p->pipes,i))
77 printf("%d ",i);
78 printf("\nuses registers (%d=mem): ",MEM);
79 for(i=0;i<=MEM;i++)
80 if(BTST(p->uses,i))
81 printf("%d ",i);
82 printf("\nmodifies registers (%d=MEM): ",MEM);
83 for(i=0;i<=MEM;i++)
84 if(BTST(p->modifies,i))
85 printf("%d ",i);
86 printf("\n\n");
87 }
88}
89void free_sinfo(void)
90{
91 int j;
92 for(j=0;j<si_count;j++)
93 free(silist[j].txt);
94}
95void output_scheduled(FILE *f)
96{
97 int pipes[PIPES],i,j,k,l,remaining;
98 int latency[MEM+1]={0},cycle=0;
99 unsigned char used[REGS_SIZE],modified[REGS_SIZE],tmp[REGS_SIZE],empty[REGS_SIZE]={0};
100 remaining=si_count;
101 if(DEBUG&2) print_sinfo();
102 while(remaining){
103 cycle++;
104 if(DEBUG&4){
105 printf("cycle %d\n",cycle);
106 for(i=0;i<=MEM;i++)
107 if(latency[i]>0) printf("latency[%d]=%d\n",i,latency[i]);
108 }
109 /* Mark all instructions which are ready. */
110 memset(modified,0,REGS_SIZE);
111 memset(used,0,REGS_SIZE);
112 for(i=0;i<si_count;i++){
113 if(silist[i].flags&OUT) continue;
114 memcpy(tmp,silist[i].uses,REGS_SIZE);
115 bvunite(tmp,silist[i].modifies,REGS_SIZE);
116 bvintersect(tmp,modified,REGS_SIZE);
117 if(bvcmp(tmp,empty,REGS_SIZE)){
118 /* uses and modifies nothing that has to be modified before */
119 memcpy(tmp,used,REGS_SIZE);
120 bvintersect(tmp,silist[i].modifies,REGS_SIZE);
121 if(bvcmp(tmp,empty,REGS_SIZE)){
122 /* modifies nothing that has to be used before */
123 for(k=0,j=0;j<=MEM;j++){
124 if(BTST(silist[i].uses,j)&&latency[j]>0) k=1;
125 }
126 if(!k) silist[i].flags|=READY;
127 }
128 }
129 bvunite(modified,silist[i].modifies,REGS_SIZE);
130 bvunite(used,silist[i].uses,REGS_SIZE);
131 }
132
133 /* Fill pipeline slots with ready instructions. */
134 for(i=0;i<PIPES;i++) pipes[i]=-1;
135 for(i=0;i<si_count;i++){
136 if(silist[i].flags&OUT) continue;
137 if(!(silist[i].flags&READY)) continue;
138 if(DEBUG&4) printf("inst ready: %s",silist[i].txt);
139 k=0;
140 /* Is there a free slot? */
141 for(j=0;!k&&j<PIPES;j++){
142 if(pipes[j]<0&&BTST(silist[i].pipes,j)){
143 pipes[j]=i;
144 k=1;
145 }
146 }
147 /* Replace a scheduled instruction with smaller latency. */
148 for(j=0;!k&&j<PIPES;j++){
149 if(BTST(silist[i].pipes,j)&&silist[i].latency>silist[pipes[j]].latency){
150 pipes[j]=i;
151 k=1;
152 }
153 }
154 }
155 if(DEBUG&4) printf("instructions for cycle %d:\n",cycle);
156 for(i=0;i<PIPES;i++){
157 if(pipes[i]>=0){
158 if(DEBUG&4) printf("%3d: %s",i,silist[pipes[i]].txt);
159 fprintf(f,"%s",silist[pipes[i]].txt);
160 silist[pipes[i]].flags|=OUT;
161 remaining--;
162 for(j=0;j<=MEM;j++){
163 if(BTST(silist[pipes[i]].modifies,j)) latency[j]=silist[pipes[i]].latency;
164 }
165 }
166 }
167 for(i=0;i<=MEM;i++)
168 if(latency[i]>0) latency[i]--;
169 }
170}
171int main(int argc,char *argv[])
172{
173 char s[LINELENGTH];int i,quiet=0;
174 FILE *in,*out; char *inname=0,*outname=0;
175 for(i=1;i<argc;i++){
176 if(*argv[i]!='-'){
177 if(!inname){
178 inname=argv[i];
179 }else{
180 if(outname){
181 printf("Only one input file allowed\n");
182 raus();
183 }else{
184 outname=argv[i];
185 }
186 }
187 }else{
188 if(!strcmp("-quiet",argv[i])) {quiet=1;continue;}
189#ifndef DEBUG
190 if(!strncmp("-debug=",argv[i],7)){DEBUG=atoi(argv[i]+7);continue;}
191#endif
192 printf("Unknown option \"%s\"\n",argv[i]);
193 raus();
194 }
195 }
196 if(!sched_init()){printf("sched_init failed\n");raus();}
197 if(!quiet){
198#ifdef SPECIAL_COPYRIGHT
199 printf("%s\n",SPECIAL_COPYRIGHT);
200#else
201 printf("%s\n%s\n",vs_copyright,tg_copyright);
202#endif
203 }
204 if(!inname){printf("No input file\n");raus();}
205 if(!outname){printf("No output file\n");raus();}
206 in=fopen(inname,"r");
207 if(!in){printf("Could not open input file \"%s\"\n",inname);raus();}
208 out=fopen(outname,"w");
209 if(!out){printf("Could not open output file \"%s\"\n",outname);raus();}
210 while(fgets(s,LINELENGTH-1,in)){
211 memset(&silist[si_count],0,sizeof(silist[0]));
212 silist[si_count].txt=mymalloc(strlen(s)+1);
213 strcpy(silist[si_count].txt,s);
214 if(!sched_info(&silist[si_count])){
215 printf("Do not understand instruction:\n%s\n",silist[si_count].txt);
216 raus();
217 }
218 if(silist[si_count].flags&(BARRIER|LABEL|COND_BRANCH|UNCOND_BRANCH)){
219 if(DEBUG&1) printf("Barrier: %s",silist[si_count].txt);
220 output_scheduled(out);
221 free_sinfo();
222 fprintf(out,silist[si_count].txt);
223 si_count=0;
224 }else{
225 if(++si_count>=MAX_INS){
226 if(DEBUG&1) printf("MAX_INS reached: %s",silist[si_count].txt);
227 output_scheduled(out);
228 free_sinfo();
229 si_count=0;
230 }
231 }
232 }
233 output_scheduled(out);
234 free_sinfo();
235 done=1;
236 raus();
237}
238
239