4 typedef struct Bitset Bitset
;
5 typedef struct Vec Vec
;
6 typedef struct Bucket Bucket
;
30 IMask
= (1<<IBits
) - 1,
34 Ins insb
[NIns
], *curi
;
36 static void *ptr
[NPtr
];
37 static void **pool
= ptr
;
40 static Bucket itbl
[IMask
+1]; /* string interning table */
53 die_(char *file
, char *s
, ...)
57 fprintf(stderr
, "%s: dying: ", file
);
59 vfprintf(stderr
, s
, ap
);
72 die("emalloc, out of memory");
84 pp
= emalloc(NPtr
* sizeof(void *));
89 return pool
[nptr
++] = emalloc(n
);
98 for (pp
= &pool
[1]; pp
< &pool
[nptr
]; pp
++)
111 vnew(ulong len
, size_t esz
, Pool pool
)
117 for (cap
=VMin
; cap
<len
; cap
*=2)
119 f
= pool
== Pheap
? emalloc
: alloc
;
120 v
= f(cap
* esz
+ sizeof(Vec
));
134 assert(v
->mag
== VMag
);
135 if (v
->pool
== Pheap
) {
142 vgrow(void *vp
, ulong len
)
148 assert(v
+1 && v
->mag
== VMag
);
151 v1
= vnew(len
, v
->esz
, v
->pool
);
152 memcpy(v1
, v
+1, v
->cap
* v
->esz
);
169 if (strcmp(s
, b
->str
[i
]) == 0)
170 return h
+ (i
<<IBits
);
172 if (n
== 1<<(32-IBits
))
173 die("interning table overflow");
175 b
->str
= vnew(1, sizeof b
->str
[0], Pheap
);
176 else if ((n
& (n
-1)) == 0)
179 b
->str
[n
] = emalloc(strlen(s
)+1);
181 strcpy(b
->str
[n
], s
);
182 return h
+ (n
<<IBits
);
188 assert(id
>>IBits
< itbl
[id
&IMask
].nstr
);
189 return itbl
[id
&IMask
].str
[id
>>IBits
];
195 return rtype(r
) == RTmp
&& r
.val
< Tmp0
;
199 iscmp(int op
, int *pk
, int *pc
)
201 if (Ocmpw
<= op
&& op
<= Ocmpw1
) {
205 else if (Ocmpl
<= op
&& op
<= Ocmpl1
) {
209 else if (Ocmps
<= op
&& op
<= Ocmps1
) {
210 *pc
= NCmpI
+ op
- Ocmps
;
213 else if (Ocmpd
<= op
&& op
<= Ocmpd1
) {
214 *pc
= NCmpI
+ op
- Ocmpd
;
223 argcls(Ins
*i
, int n
)
225 return optab
[i
->op
].argcls
[n
][i
->cls
];
229 emit(int op
, int k
, Ref to
, Ref arg0
, Ref arg1
)
232 die("emit, too many instructions");
235 .to
= to
, .arg
= {arg0
, arg1
}
242 emit(i
.op
, i
.cls
, i
.to
, i
.arg
[0], i
.arg
[1]);
246 idup(Ins
**pd
, Ins
*s
, ulong n
)
248 *pd
= alloc(n
* sizeof(Ins
));
249 memcpy(*pd
, s
, n
* sizeof(Ins
));
253 icpy(Ins
*d
, Ins
*s
, ulong n
)
255 memcpy(d
, s
, n
* sizeof(Ins
));
259 static int cmptab
[][2] ={
261 [Ciule
] = {Ciugt
, Ciuge
},
262 [Ciult
] = {Ciuge
, Ciugt
},
263 [Ciugt
] = {Ciule
, Ciult
},
264 [Ciuge
] = {Ciult
, Ciule
},
265 [Cisle
] = {Cisgt
, Cisge
},
266 [Cislt
] = {Cisge
, Cisgt
},
267 [Cisgt
] = {Cisle
, Cislt
},
268 [Cisge
] = {Cislt
, Cisle
},
269 [Cieq
] = {Cine
, Cieq
},
270 [Cine
] = {Cieq
, Cine
},
271 [NCmpI
+Cfle
] = {NCmpI
+Cfgt
, NCmpI
+Cfge
},
272 [NCmpI
+Cflt
] = {NCmpI
+Cfge
, NCmpI
+Cfgt
},
273 [NCmpI
+Cfgt
] = {NCmpI
+Cfle
, NCmpI
+Cflt
},
274 [NCmpI
+Cfge
] = {NCmpI
+Cflt
, NCmpI
+Cfle
},
275 [NCmpI
+Cfeq
] = {NCmpI
+Cfne
, NCmpI
+Cfeq
},
276 [NCmpI
+Cfne
] = {NCmpI
+Cfeq
, NCmpI
+Cfne
},
277 [NCmpI
+Cfo
] = {NCmpI
+Cfuo
, NCmpI
+Cfo
},
278 [NCmpI
+Cfuo
] = {NCmpI
+Cfo
, NCmpI
+Cfuo
},
284 assert(0 <= c
&& c
< NCmp
);
291 assert(0 <= c
&& c
< NCmp
);
296 clsmerge(short *pk
, short k
)
305 if ((k1
== Kw
&& k
== Kl
) || (k1
== Kl
&& k
== Kw
)) {
313 phicls(int t
, Tmp
*tmp
)
320 t1
= phicls(t1
, tmp
);
326 newtmp(char *prfx
, int k
, Fn
*fn
)
332 vgrow(&fn
->tmp
, fn
->ntmp
);
333 memset(&fn
->tmp
[t
], 0, sizeof(Tmp
));
335 sprintf(fn
->tmp
[t
].name
, "%s.%d", prfx
, ++n
);
337 fn
->tmp
[t
].slot
= -1;
338 fn
->tmp
[t
].nuse
= +1;
339 fn
->tmp
[t
].ndef
= +1;
344 chuse(Ref r
, int du
, Fn
*fn
)
346 if (rtype(r
) == RTmp
)
347 fn
->tmp
[r
.val
].nuse
+= du
;
351 getcon(int64_t val
, Fn
*fn
)
355 for (c
=0; c
<fn
->ncon
; c
++)
356 if (fn
->con
[c
].type
== CBits
&& fn
->con
[c
].bits
.i
== val
)
358 vgrow(&fn
->con
, ++fn
->ncon
);
359 fn
->con
[c
] = (Con
){.type
= CBits
, .bits
.i
= val
};
364 addcon(Con
*c0
, Con
*c1
)
366 if (c0
->type
== CUndef
)
369 if (c1
->type
== CAddr
) {
370 assert(c0
->type
!= CAddr
&& "adding two addresses");
372 c0
->label
= c1
->label
;
374 c0
->bits
.i
+= c1
->bits
.i
;
379 blit(Ref rdst
, uint doff
, Ref rsrc
, uint sz
, Fn
*fn
)
381 struct { int st
, ld
, cls
, size
; } *p
, tbl
[] = {
382 { Ostorel
, Oload
, Kl
, 8 },
383 { Ostorew
, Oload
, Kw
, 8 },
384 { Ostoreh
, Oloaduh
, Kw
, 2 },
385 { Ostoreb
, Oloadub
, Kw
, 1 }
390 for (boff
=0, p
=tbl
; sz
; p
++)
391 for (s
=p
->size
; sz
>=s
; sz
-=s
, doff
+=s
, boff
+=s
) {
392 r
= newtmp("blt", Kl
, fn
);
393 r1
= newtmp("blt", Kl
, fn
);
394 emit(p
->st
, 0, R
, r
, r1
);
395 emit(Oadd
, Kl
, r1
, rdst
, getcon(doff
, fn
));
396 r1
= newtmp("blt", Kl
, fn
);
397 emit(p
->ld
, p
->cls
, r
, r1
, R
);
398 emit(Oadd
, Kl
, r1
, rsrc
, getcon(boff
, fn
));
403 bsinit(BSet
*bs
, uint n
)
405 n
= (n
+ NBit
-1) / NBit
;
407 bs
->t
= alloc(n
* sizeof bs
->t
[0]);
410 MAKESURE(NBit_is_64
, NBit
== 64);
414 b
= (b
& 0x5555555555555555) + ((b
>>1) & 0x5555555555555555);
415 b
= (b
& 0x3333333333333333) + ((b
>>2) & 0x3333333333333333);
416 b
= (b
& 0x0f0f0f0f0f0f0f0f) + ((b
>>4) & 0x0f0f0f0f0f0f0f0f);
429 if (!(b
& 0xffffffff)) {
445 n
+= (char[16]){4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}[b
& 0xf];
455 for (i
=0; i
<bs
->nt
; i
++)
456 n
+= popcnt(bs
->t
[i
]);
463 return bs
->nt
* NBit
;
467 bsset(BSet
*bs
, uint elt
)
469 assert(elt
< bsmax(bs
));
470 bs
->t
[elt
/NBit
] |= BIT(elt
%NBit
);
474 bsclr(BSet
*bs
, uint elt
)
476 assert(elt
< bsmax(bs
));
477 bs
->t
[elt
/NBit
] &= ~BIT(elt
%NBit
);
480 #define BSOP(f, op) \
482 f(BSet *a, BSet *b) \
486 assert(a->nt == b->nt); \
487 for (i=0; i<a->nt; i++) \
488 a->t[i] op b->t[i]; \
497 bsequal(BSet
*a
, BSet
*b
)
501 assert(a
->nt
== b
->nt
);
502 for (i
=0; i
<a
->nt
; i
++)
503 if (a
->t
[i
] != b
->t
[i
])
511 memset(bs
->t
, 0, bs
->nt
* sizeof bs
->t
[0]);
514 /* iterates on a bitset, use as follows
516 * for (i=0; bsiter(set, &i); i++)
521 bsiter(BSet
*bs
, int *elt
)
531 b
&= ~(BIT(i
%NBit
) - 1);
538 *elt
= NBit
*t
+ firstbit(b
);
543 dumpts(BSet
*bs
, Tmp
*tmp
, FILE *f
)
548 for (t
=Tmp0
; bsiter(bs
, &t
); t
++)
549 fprintf(f
, " %s", tmp
[t
].name
);