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
);
158 strf(char str
[NString
], char *s
, ...)
163 vsnprintf(str
, NString
, s
, ap
);
179 if (strcmp(s
, b
->str
[i
]) == 0)
180 return h
+ (i
<<IBits
);
182 if (n
== 1<<(32-IBits
))
183 die("interning table overflow");
185 b
->str
= vnew(1, sizeof b
->str
[0], PHeap
);
186 else if ((n
& (n
-1)) == 0)
189 b
->str
[n
] = emalloc(strlen(s
)+1);
191 strcpy(b
->str
[n
], s
);
192 return h
+ (n
<<IBits
);
198 assert(id
>>IBits
< itbl
[id
&IMask
].nstr
);
199 return itbl
[id
&IMask
].str
[id
>>IBits
];
205 return rtype(r
) == RTmp
&& r
.val
< Tmp0
;
209 iscmp(int op
, int *pk
, int *pc
)
211 if (Ocmpw
<= op
&& op
<= Ocmpw1
) {
215 else if (Ocmpl
<= op
&& op
<= Ocmpl1
) {
219 else if (Ocmps
<= op
&& op
<= Ocmps1
) {
220 *pc
= NCmpI
+ op
- Ocmps
;
223 else if (Ocmpd
<= op
&& op
<= Ocmpd1
) {
224 *pc
= NCmpI
+ op
- Ocmpd
;
233 argcls(Ins
*i
, int n
)
235 return optab
[i
->op
].argcls
[n
][i
->cls
];
239 emit(int op
, int k
, Ref to
, Ref arg0
, Ref arg1
)
242 die("emit, too many instructions");
245 .to
= to
, .arg
= {arg0
, arg1
}
252 emit(i
.op
, i
.cls
, i
.to
, i
.arg
[0], i
.arg
[1]);
256 idup(Ins
**pd
, Ins
*s
, ulong n
)
258 *pd
= alloc(n
* sizeof(Ins
));
260 memcpy(*pd
, s
, n
* sizeof(Ins
));
264 icpy(Ins
*d
, Ins
*s
, ulong n
)
267 memcpy(d
, s
, n
* sizeof(Ins
));
271 static int cmptab
[][2] ={
273 [Ciule
] = {Ciugt
, Ciuge
},
274 [Ciult
] = {Ciuge
, Ciugt
},
275 [Ciugt
] = {Ciule
, Ciult
},
276 [Ciuge
] = {Ciult
, Ciule
},
277 [Cisle
] = {Cisgt
, Cisge
},
278 [Cislt
] = {Cisge
, Cisgt
},
279 [Cisgt
] = {Cisle
, Cislt
},
280 [Cisge
] = {Cislt
, Cisle
},
281 [Cieq
] = {Cine
, Cieq
},
282 [Cine
] = {Cieq
, Cine
},
283 [NCmpI
+Cfle
] = {NCmpI
+Cfgt
, NCmpI
+Cfge
},
284 [NCmpI
+Cflt
] = {NCmpI
+Cfge
, NCmpI
+Cfgt
},
285 [NCmpI
+Cfgt
] = {NCmpI
+Cfle
, NCmpI
+Cflt
},
286 [NCmpI
+Cfge
] = {NCmpI
+Cflt
, NCmpI
+Cfle
},
287 [NCmpI
+Cfeq
] = {NCmpI
+Cfne
, NCmpI
+Cfeq
},
288 [NCmpI
+Cfne
] = {NCmpI
+Cfeq
, NCmpI
+Cfne
},
289 [NCmpI
+Cfo
] = {NCmpI
+Cfuo
, NCmpI
+Cfo
},
290 [NCmpI
+Cfuo
] = {NCmpI
+Cfo
, NCmpI
+Cfuo
},
296 assert(0 <= c
&& c
< NCmp
);
303 assert(0 <= c
&& c
< NCmp
);
308 clsmerge(short *pk
, short k
)
317 if ((k1
== Kw
&& k
== Kl
) || (k1
== Kl
&& k
== Kw
)) {
325 phicls(int t
, Tmp
*tmp
)
332 t1
= phicls(t1
, tmp
);
338 newtmp(char *prfx
, int k
, Fn
*fn
)
344 vgrow(&fn
->tmp
, fn
->ntmp
);
345 memset(&fn
->tmp
[t
], 0, sizeof(Tmp
));
347 strf(fn
->tmp
[t
].name
, "%s.%d", prfx
, ++n
);
349 fn
->tmp
[t
].slot
= -1;
350 fn
->tmp
[t
].nuse
= +1;
351 fn
->tmp
[t
].ndef
= +1;
356 chuse(Ref r
, int du
, Fn
*fn
)
358 if (rtype(r
) == RTmp
)
359 fn
->tmp
[r
.val
].nuse
+= du
;
363 symeq(Sym s0
, Sym s1
)
365 return s0
.type
== s1
.type
&& s0
.id
== s1
.id
;
369 newcon(Con
*c0
, Fn
*fn
)
374 for (i
=1; i
<fn
->ncon
; i
++) {
376 if (c0
->type
== c1
->type
377 && symeq(c0
->sym
, c1
->sym
)
378 && c0
->bits
.i
== c1
->bits
.i
)
381 vgrow(&fn
->con
, ++fn
->ncon
);
387 getcon(int64_t val
, Fn
*fn
)
391 for (c
=1; c
<fn
->ncon
; c
++)
392 if (fn
->con
[c
].type
== CBits
393 && fn
->con
[c
].bits
.i
== val
)
395 vgrow(&fn
->con
, ++fn
->ncon
);
396 fn
->con
[c
] = (Con
){.type
= CBits
, .bits
.i
= val
};
401 addcon(Con
*c0
, Con
*c1
, int m
)
403 if (m
!= 1 && c1
->type
== CAddr
)
405 if (c0
->type
== CUndef
) {
409 if (c1
->type
== CAddr
) {
410 if (c0
->type
== CAddr
)
415 c0
->bits
.i
+= c1
->bits
.i
* m
;
421 salloc(Ref rt
, Ref rs
, Fn
*fn
)
426 /* we need to make sure
427 * the stack remains aligned
431 if (rtype(rs
) == RCon
) {
432 sz
= fn
->con
[rs
.val
].bits
.i
;
433 if (sz
< 0 || sz
>= INT_MAX
-15)
434 err("invalid alloc size %"PRId64
, sz
);
435 sz
= (sz
+ 15) & -16;
436 emit(Osalloc
, Kl
, rt
, getcon(sz
, fn
), R
);
438 /* r0 = (r + 15) & -16 */
439 r0
= newtmp("isel", Kl
, fn
);
440 r1
= newtmp("isel", Kl
, fn
);
441 emit(Osalloc
, Kl
, rt
, r0
, R
);
442 emit(Oand
, Kl
, r0
, r1
, getcon(-16, fn
));
443 emit(Oadd
, Kl
, r1
, rs
, getcon(15, fn
));
444 if (fn
->tmp
[rs
.val
].slot
!= -1)
445 err("unlikely alloc argument %%%s for %%%s",
446 fn
->tmp
[rs
.val
].name
, fn
->tmp
[rt
.val
].name
);
451 bsinit(BSet
*bs
, uint n
)
453 n
= (n
+ NBit
-1) / NBit
;
455 bs
->t
= alloc(n
* sizeof bs
->t
[0]);
458 MAKESURE(NBit_is_64
, NBit
== 64);
462 b
= (b
& 0x5555555555555555) + ((b
>>1) & 0x5555555555555555);
463 b
= (b
& 0x3333333333333333) + ((b
>>2) & 0x3333333333333333);
464 b
= (b
& 0x0f0f0f0f0f0f0f0f) + ((b
>>4) & 0x0f0f0f0f0f0f0f0f);
477 if (!(b
& 0xffffffff)) {
493 n
+= (char[16]){4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}[b
& 0xf];
503 for (i
=0; i
<bs
->nt
; i
++)
504 n
+= popcnt(bs
->t
[i
]);
511 return bs
->nt
* NBit
;
515 bsset(BSet
*bs
, uint elt
)
517 assert(elt
< bsmax(bs
));
518 bs
->t
[elt
/NBit
] |= BIT(elt
%NBit
);
522 bsclr(BSet
*bs
, uint elt
)
524 assert(elt
< bsmax(bs
));
525 bs
->t
[elt
/NBit
] &= ~BIT(elt
%NBit
);
528 #define BSOP(f, op) \
530 f(BSet *a, BSet *b) \
534 assert(a->nt == b->nt); \
535 for (i=0; i<a->nt; i++) \
536 a->t[i] op b->t[i]; \
545 bsequal(BSet
*a
, BSet
*b
)
549 assert(a
->nt
== b
->nt
);
550 for (i
=0; i
<a
->nt
; i
++)
551 if (a
->t
[i
] != b
->t
[i
])
559 memset(bs
->t
, 0, bs
->nt
* sizeof bs
->t
[0]);
562 /* iterates on a bitset, use as follows
564 * for (i=0; bsiter(set, &i); i++)
569 bsiter(BSet
*bs
, int *elt
)
579 b
&= ~(BIT(i
%NBit
) - 1);
586 *elt
= NBit
*t
+ firstbit(b
);
591 dumpts(BSet
*bs
, Tmp
*tmp
, FILE *f
)
596 for (t
=Tmp0
; bsiter(bs
, &t
); t
++)
597 fprintf(f
, " %s", tmp
[t
].name
);
602 runmatch(uchar
*code
, Num
*tn
, Ref ref
, Ref
*var
)
604 Ref stkbuf
[20], *stk
;
609 assert(rtype(ref
) == RTmp
);
614 case 1: /* pushsym */
616 assert(stk
< &stkbuf
[20]);
617 assert(rtype(ref
) == RTmp
);
620 if (bc
== 1 && nl
> nr
) {
621 *stk
++ = tn
[ref
.val
].l
;
624 *stk
++ = tn
[ref
.val
].r
;
635 assert(stk
> &stkbuf
[0]);
640 assert(rtype(ref
) == RTmp
);
643 for (i
=*s
++; i
>0; i
--, s
++)
650 pc
= code
+ (bc
- 10);