4 typedef struct Bitset Bitset
;
5 typedef struct Vec Vec
;
26 Ins insb
[NIns
], *curi
;
28 static void *ptr
[NPtr
];
29 static void **pool
= ptr
;
33 die_(char *file
, char *s
, ...)
37 fprintf(stderr
, "%s: dying: ", file
);
39 vfprintf(stderr
, s
, ap
);
52 die("emalloc, out of memory");
64 pp
= emalloc(NPtr
* sizeof(void *));
69 return pool
[nptr
++] = emalloc(n
);
78 for (pp
= &pool
[1]; pp
< &pool
[nptr
]; pp
++)
91 iscmp(int op
, int *pk
, int *pc
)
93 if (Ocmpw
<= op
&& op
<= Ocmpw1
) {
97 else if (Ocmpl
<= op
&& op
<= Ocmpl1
) {
101 else if (Ocmps
<= op
&& op
<= Ocmps1
) {
102 *pc
= NCmpI
+ op
- Ocmps
;
105 else if (Ocmpd
<= op
&& op
<= Ocmpd1
) {
106 *pc
= NCmpI
+ op
- Ocmpd
;
115 argcls(Ins
*i
, int n
)
117 return optab
[i
->op
].argcls
[n
][i
->cls
];
121 emit(int op
, int k
, Ref to
, Ref arg0
, Ref arg1
)
124 die("emit, too many instructions");
127 .to
= to
, .arg
= {arg0
, arg1
}
134 emit(i
.op
, i
.cls
, i
.to
, i
.arg
[0], i
.arg
[1]);
138 idup(Ins
**pd
, Ins
*s
, ulong n
)
140 *pd
= alloc(n
* sizeof(Ins
));
141 memcpy(*pd
, s
, n
* sizeof(Ins
));
145 icpy(Ins
*d
, Ins
*s
, ulong n
)
147 memcpy(d
, s
, n
* sizeof(Ins
));
152 vnew(ulong len
, size_t esz
, Pool pool
)
158 for (cap
=VMin
; cap
<len
; cap
*=2)
160 f
= pool
== Pheap
? emalloc
: alloc
;
161 v
= f(cap
* esz
+ sizeof(Vec
));
175 assert(v
->mag
== VMag
);
176 if (v
->pool
== Pheap
) {
183 vgrow(void *vp
, ulong len
)
189 assert(v
+1 && v
->mag
== VMag
);
192 v1
= vnew(len
, v
->esz
, v
->pool
);
193 memcpy(v1
, v
+1, v
->cap
* v
->esz
);
198 static int cmptab
[][2] ={
200 [Ciule
] = {Ciugt
, Ciuge
},
201 [Ciult
] = {Ciuge
, Ciugt
},
202 [Ciugt
] = {Ciule
, Ciult
},
203 [Ciuge
] = {Ciult
, Ciule
},
204 [Cisle
] = {Cisgt
, Cisge
},
205 [Cislt
] = {Cisge
, Cisgt
},
206 [Cisgt
] = {Cisle
, Cislt
},
207 [Cisge
] = {Cislt
, Cisle
},
208 [Cieq
] = {Cine
, Cieq
},
209 [Cine
] = {Cieq
, Cine
},
210 [NCmpI
+Cfle
] = {NCmpI
+Cfgt
, NCmpI
+Cfge
},
211 [NCmpI
+Cflt
] = {NCmpI
+Cfge
, NCmpI
+Cfgt
},
212 [NCmpI
+Cfgt
] = {NCmpI
+Cfle
, NCmpI
+Cflt
},
213 [NCmpI
+Cfge
] = {NCmpI
+Cflt
, NCmpI
+Cfle
},
214 [NCmpI
+Cfeq
] = {NCmpI
+Cfne
, NCmpI
+Cfeq
},
215 [NCmpI
+Cfne
] = {NCmpI
+Cfeq
, NCmpI
+Cfne
},
216 [NCmpI
+Cfo
] = {NCmpI
+Cfuo
, NCmpI
+Cfo
},
217 [NCmpI
+Cfuo
] = {NCmpI
+Cfo
, NCmpI
+Cfuo
},
223 assert(0 <= c
&& c
< NCmp
);
230 assert(0 <= c
&& c
< NCmp
);
235 clsmerge(short *pk
, short k
)
244 if ((k1
== Kw
&& k
== Kl
) || (k1
== Kl
&& k
== Kw
)) {
252 phicls(int t
, Tmp
*tmp
/*, int c*/)
264 t1
= phitmp(t1
, tmp
, c
);
273 newtmp(char *prfx
, int k
, Fn
*fn
)
279 vgrow(&fn
->tmp
, fn
->ntmp
);
280 memset(&fn
->tmp
[t
], 0, sizeof(Tmp
));
282 sprintf(fn
->tmp
[t
].name
, "%s.%d", prfx
, ++n
);
284 fn
->tmp
[t
].slot
= -1;
285 fn
->tmp
[t
].nuse
= +1;
286 fn
->tmp
[t
].ndef
= +1;
291 chuse(Ref r
, int du
, Fn
*fn
)
293 if (rtype(r
) == RTmp
)
294 fn
->tmp
[r
.val
].nuse
+= du
;
298 getcon(int64_t val
, Fn
*fn
)
302 for (c
=0; c
<fn
->ncon
; c
++)
303 if (fn
->con
[c
].type
== CBits
&& fn
->con
[c
].bits
.i
== val
)
305 vgrow(&fn
->con
, ++fn
->ncon
);
306 fn
->con
[c
] = (Con
){.type
= CBits
, .bits
.i
= val
};
311 addcon(Con
*c0
, Con
*c1
)
313 if (c0
->type
== CUndef
)
316 if (c1
->type
== CAddr
) {
317 assert(c0
->type
!= CAddr
&& "adding two addresses");
319 strcpy(c0
->label
, c1
->label
);
321 c0
->bits
.i
+= c1
->bits
.i
;
326 blit(Ref rdst
, uint doff
, Ref rsrc
, uint sz
, Fn
*fn
)
328 struct { int st
, ld
, cls
, size
; } *p
, tbl
[] = {
329 { Ostorel
, Oload
, Kl
, 8 },
330 { Ostorew
, Oload
, Kw
, 8 },
331 { Ostoreh
, Oloaduh
, Kw
, 2 },
332 { Ostoreb
, Oloadub
, Kw
, 1 }
337 for (boff
=0, p
=tbl
; sz
; p
++)
338 for (s
=p
->size
; sz
>=s
; sz
-=s
, doff
+=s
, boff
+=s
) {
339 r
= newtmp("blt", Kl
, fn
);
340 r1
= newtmp("blt", Kl
, fn
);
341 emit(p
->st
, 0, R
, r
, r1
);
342 emit(Oadd
, Kl
, r1
, rdst
, getcon(doff
, fn
));
343 r1
= newtmp("blt", Kl
, fn
);
344 emit(p
->ld
, p
->cls
, r
, r1
, R
);
345 emit(Oadd
, Kl
, r1
, rsrc
, getcon(boff
, fn
));
350 bsinit(BSet
*bs
, uint n
)
352 n
= (n
+ NBit
-1) / NBit
;
354 bs
->t
= alloc(n
* sizeof bs
->t
[0]);
357 MAKESURE(NBit_is_64
, NBit
== 64);
361 b
= (b
& 0x5555555555555555) + ((b
>>1) & 0x5555555555555555);
362 b
= (b
& 0x3333333333333333) + ((b
>>2) & 0x3333333333333333);
363 b
= (b
& 0x0f0f0f0f0f0f0f0f) + ((b
>>4) & 0x0f0f0f0f0f0f0f0f);
376 if (!(b
& 0xffffffff)) {
392 n
+= (char[16]){4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}[b
& 0xf];
402 for (i
=0; i
<bs
->nt
; i
++)
403 n
+= popcnt(bs
->t
[i
]);
410 return bs
->nt
* NBit
;
414 bsset(BSet
*bs
, uint elt
)
416 assert(elt
< bsmax(bs
));
417 bs
->t
[elt
/NBit
] |= BIT(elt
%NBit
);
421 bsclr(BSet
*bs
, uint elt
)
423 assert(elt
< bsmax(bs
));
424 bs
->t
[elt
/NBit
] &= ~BIT(elt
%NBit
);
427 #define BSOP(f, op) \
429 f(BSet *a, BSet *b) \
433 assert(a->nt == b->nt); \
434 for (i=0; i<a->nt; i++) \
435 a->t[i] op b->t[i]; \
444 bsequal(BSet
*a
, BSet
*b
)
448 assert(a
->nt
== b
->nt
);
449 for (i
=0; i
<a
->nt
; i
++)
450 if (a
->t
[i
] != b
->t
[i
])
458 memset(bs
->t
, 0, bs
->nt
* sizeof bs
->t
[0]);
461 /* iterates on a bitset, use as follows
463 * for (i=0; bsiter(set, &i); i++)
468 bsiter(BSet
*bs
, int *elt
)
478 b
&= ~(BIT(i
%NBit
) - 1);
485 *elt
= NBit
*t
+ firstbit(b
);
490 dumpts(BSet
*bs
, Tmp
*tmp
, FILE *f
)
495 for (t
=Tmp0
; bsiter(bs
, &t
); t
++)
496 fprintf(f
, " %s", tmp
[t
].name
);