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
));
250 memcpy(*pd
, s
, n
* sizeof(Ins
));
254 icpy(Ins
*d
, Ins
*s
, ulong n
)
257 memcpy(d
, s
, n
* sizeof(Ins
));
261 static int cmptab
[][2] ={
263 [Ciule
] = {Ciugt
, Ciuge
},
264 [Ciult
] = {Ciuge
, Ciugt
},
265 [Ciugt
] = {Ciule
, Ciult
},
266 [Ciuge
] = {Ciult
, Ciule
},
267 [Cisle
] = {Cisgt
, Cisge
},
268 [Cislt
] = {Cisge
, Cisgt
},
269 [Cisgt
] = {Cisle
, Cislt
},
270 [Cisge
] = {Cislt
, Cisle
},
271 [Cieq
] = {Cine
, Cieq
},
272 [Cine
] = {Cieq
, Cine
},
273 [NCmpI
+Cfle
] = {NCmpI
+Cfgt
, NCmpI
+Cfge
},
274 [NCmpI
+Cflt
] = {NCmpI
+Cfge
, NCmpI
+Cfgt
},
275 [NCmpI
+Cfgt
] = {NCmpI
+Cfle
, NCmpI
+Cflt
},
276 [NCmpI
+Cfge
] = {NCmpI
+Cflt
, NCmpI
+Cfle
},
277 [NCmpI
+Cfeq
] = {NCmpI
+Cfne
, NCmpI
+Cfeq
},
278 [NCmpI
+Cfne
] = {NCmpI
+Cfeq
, NCmpI
+Cfne
},
279 [NCmpI
+Cfo
] = {NCmpI
+Cfuo
, NCmpI
+Cfo
},
280 [NCmpI
+Cfuo
] = {NCmpI
+Cfo
, NCmpI
+Cfuo
},
286 assert(0 <= c
&& c
< NCmp
);
293 assert(0 <= c
&& c
< NCmp
);
298 clsmerge(short *pk
, short k
)
307 if ((k1
== Kw
&& k
== Kl
) || (k1
== Kl
&& k
== Kw
)) {
315 phicls(int t
, Tmp
*tmp
)
322 t1
= phicls(t1
, tmp
);
328 newtmp(char *prfx
, int k
, Fn
*fn
)
334 vgrow(&fn
->tmp
, fn
->ntmp
);
335 memset(&fn
->tmp
[t
], 0, sizeof(Tmp
));
337 sprintf(fn
->tmp
[t
].name
, "%s.%d", prfx
, ++n
);
339 fn
->tmp
[t
].slot
= -1;
340 fn
->tmp
[t
].nuse
= +1;
341 fn
->tmp
[t
].ndef
= +1;
346 chuse(Ref r
, int du
, Fn
*fn
)
348 if (rtype(r
) == RTmp
)
349 fn
->tmp
[r
.val
].nuse
+= du
;
353 newcon(Con
*c0
, Fn
*fn
)
358 for (i
=0; i
<fn
->ncon
; i
++) {
360 if (c0
->type
== c1
->type
361 && c0
->label
== c1
->label
362 && c0
->bits
.i
== c1
->bits
.i
363 && c0
->reloc
== c1
->reloc
)
366 vgrow(&fn
->con
, ++fn
->ncon
);
372 getcon(int64_t val
, Fn
*fn
)
376 for (c
=0; c
<fn
->ncon
; c
++)
377 if (fn
->con
[c
].type
== CBits
&& fn
->con
[c
].bits
.i
== val
)
379 vgrow(&fn
->con
, ++fn
->ncon
);
380 fn
->con
[c
] = (Con
){.type
= CBits
, .bits
.i
= val
};
385 addcon(Con
*c0
, Con
*c1
)
387 if (c0
->type
== CUndef
)
390 if (c1
->type
== CAddr
) {
391 if (c0
->type
== CAddr
)
394 c0
->label
= c1
->label
;
396 c0
->bits
.i
+= c1
->bits
.i
;
402 blit(Ref rdst
, uint doff
, Ref rsrc
, uint boff
, uint sz
, Fn
*fn
)
404 struct { int st
, ld
, cls
, size
; } *p
, tbl
[] = {
405 { Ostorel
, Oload
, Kl
, 8 },
406 { Ostorew
, Oload
, Kw
, 4 },
407 { Ostoreh
, Oloaduh
, Kw
, 2 },
408 { Ostoreb
, Oloadub
, Kw
, 1 }
414 for (s
=p
->size
; sz
>=s
; sz
-=s
, doff
+=s
, boff
+=s
) {
415 r
= newtmp("blt", Kl
, fn
);
416 r1
= newtmp("blt", Kl
, fn
);
417 emit(p
->st
, 0, R
, r
, r1
);
418 emit(Oadd
, Kl
, r1
, rdst
, getcon(doff
, fn
));
419 r1
= newtmp("blt", Kl
, fn
);
420 emit(p
->ld
, p
->cls
, r
, r1
, R
);
421 emit(Oadd
, Kl
, r1
, rsrc
, getcon(boff
, fn
));
426 blit0(Ref rdst
, Ref rsrc
, uint sz
, Fn
*fn
)
428 blit(rdst
, 0, rsrc
, 0, sz
, fn
);
432 salloc(Ref rt
, Ref rs
, Fn
*fn
)
437 /* we need to make sure
438 * the stack remains aligned
442 if (rtype(rs
) == RCon
) {
443 sz
= fn
->con
[rs
.val
].bits
.i
;
444 if (sz
< 0 || sz
>= INT_MAX
-15)
445 err("invalid alloc size %"PRId64
, sz
);
446 sz
= (sz
+ 15) & -16;
447 emit(Osalloc
, Kl
, rt
, getcon(sz
, fn
), R
);
449 /* r0 = (r + 15) & -16 */
450 r0
= newtmp("isel", Kl
, fn
);
451 r1
= newtmp("isel", Kl
, fn
);
452 emit(Osalloc
, Kl
, rt
, r0
, R
);
453 emit(Oand
, Kl
, r0
, r1
, getcon(-16, fn
));
454 emit(Oadd
, Kl
, r1
, rs
, getcon(15, fn
));
455 if (fn
->tmp
[rs
.val
].slot
!= -1)
456 err("unlikely alloc argument %%%s for %%%s",
457 fn
->tmp
[rs
.val
].name
, fn
->tmp
[rt
.val
].name
);
462 bsinit(BSet
*bs
, uint n
)
464 n
= (n
+ NBit
-1) / NBit
;
466 bs
->t
= alloc(n
* sizeof bs
->t
[0]);
469 MAKESURE(NBit_is_64
, NBit
== 64);
473 b
= (b
& 0x5555555555555555) + ((b
>>1) & 0x5555555555555555);
474 b
= (b
& 0x3333333333333333) + ((b
>>2) & 0x3333333333333333);
475 b
= (b
& 0x0f0f0f0f0f0f0f0f) + ((b
>>4) & 0x0f0f0f0f0f0f0f0f);
488 if (!(b
& 0xffffffff)) {
504 n
+= (char[16]){4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}[b
& 0xf];
514 for (i
=0; i
<bs
->nt
; i
++)
515 n
+= popcnt(bs
->t
[i
]);
522 return bs
->nt
* NBit
;
526 bsset(BSet
*bs
, uint elt
)
528 assert(elt
< bsmax(bs
));
529 bs
->t
[elt
/NBit
] |= BIT(elt
%NBit
);
533 bsclr(BSet
*bs
, uint elt
)
535 assert(elt
< bsmax(bs
));
536 bs
->t
[elt
/NBit
] &= ~BIT(elt
%NBit
);
539 #define BSOP(f, op) \
541 f(BSet *a, BSet *b) \
545 assert(a->nt == b->nt); \
546 for (i=0; i<a->nt; i++) \
547 a->t[i] op b->t[i]; \
556 bsequal(BSet
*a
, BSet
*b
)
560 assert(a
->nt
== b
->nt
);
561 for (i
=0; i
<a
->nt
; i
++)
562 if (a
->t
[i
] != b
->t
[i
])
570 memset(bs
->t
, 0, bs
->nt
* sizeof bs
->t
[0]);
573 /* iterates on a bitset, use as follows
575 * for (i=0; bsiter(set, &i); i++)
580 bsiter(BSet
*bs
, int *elt
)
590 b
&= ~(BIT(i
%NBit
) - 1);
597 *elt
= NBit
*t
+ firstbit(b
);
602 dumpts(BSet
*bs
, Tmp
*tmp
, FILE *f
)
607 for (t
=Tmp0
; bsiter(bs
, &t
); t
++)
608 fprintf(f
, " %s", tmp
[t
].name
);