148 lines
5.9 KiB
Python
148 lines
5.9 KiB
Python
#!/usr/bin/env python3
|
|
# Emits the C source of the smoke check "i64 compares", with kExp holding
|
|
# the expected results computed here (C semantics).
|
|
#
|
|
# Every i64 predicate (eq ne ult ule ugt uge slt sle sgt sge) on values
|
|
# that sit on each 16-bit word boundary and both sides of the sign bit: as
|
|
# a branch, as a 0/1 value and as an i16 select against registers, and as
|
|
# a branch and a value against ten constants (some with zero low words,
|
|
# which lowerI32Cmp drops from its CMP/SBC chain), then loops whose i64
|
|
# counters cross a 32-bit boundary. Pins the four-word CMP/SBC chain
|
|
# (SETCC / BR_CC / SELECT_CC on i64 are lowered by lowerI32Cmp).
|
|
#
|
|
# Mailbox: 0x025000 = mismatches, 0x025002 = first failing case,
|
|
# 0x025004 = 0xC0DE when done.
|
|
V = [
|
|
0x0000000000000000, 0x0000000000000001, 0x000000000000FFFF,
|
|
0x0000000000010000, 0x00000000FFFFFFFF, 0x0000000100000000,
|
|
0x0000000100000001, 0x0000FFFFFFFFFFFF, 0x0001000000000000,
|
|
0x0000800000000000, 0x7FF0000000000000, 0x7FF0000000000001,
|
|
0x0001FFFF00000000, 0x7FFFFFFFFFFFFFFF, 0x8000000000000000,
|
|
0x8000000000000001, 0xFFFF000000000000, 0xFFFFFFFF00000000,
|
|
0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFFFFFF,
|
|
]
|
|
K = [
|
|
0x0000000000000000, 0x0000000000000001, 0x00000000FFFFFFFF,
|
|
0x0000000100000000, 0x7FF0000000000000, 0x7FF0000000000001,
|
|
0x7FFFFFFFFFFFFFFF, 0x8000000000000000, 0xFFFF000000000000,
|
|
0xFFFFFFFFFFFFFFFF,
|
|
]
|
|
PREDS = [
|
|
("eq", "u64", "=="), ("ne", "u64", "!="), ("ult", "u64", "<"),
|
|
("ule", "u64", "<="), ("ugt", "u64", ">"), ("uge", "u64", ">="),
|
|
("slt", "s64", "<"), ("sle", "s64", "<="), ("sgt", "s64", ">"),
|
|
("sge", "s64", ">="),
|
|
]
|
|
|
|
|
|
def s64(x):
|
|
return x - (1 << 64) if x & (1 << 63) else x
|
|
|
|
|
|
def ev(t, op, a, b):
|
|
if t == "s64":
|
|
a, b = s64(a), s64(b)
|
|
return {"==": a == b, "!=": a != b, "<": a < b, "<=": a <= b,
|
|
">": a > b, ">=": a >= b}[op]
|
|
|
|
|
|
bits = []
|
|
for _, t, op in PREDS:
|
|
for a in V:
|
|
for b in V:
|
|
bits.append(ev(t, op, a, b))
|
|
for _, t, op in PREDS:
|
|
for k in K:
|
|
for a in V:
|
|
bits.append(ev(t, op, a, k))
|
|
exp = bytearray((len(bits) + 7) // 8)
|
|
for i, b in enumerate(bits):
|
|
if b:
|
|
exp[i >> 3] |= 1 << (i & 7)
|
|
|
|
o = []
|
|
w = o.append
|
|
w("// i64 compares, generated by tests/regress/genI64Cmp.py; see there.")
|
|
w("typedef unsigned char u8;")
|
|
w("typedef unsigned short u16;")
|
|
w("typedef unsigned long long u64;")
|
|
w("typedef long long s64;")
|
|
w("#define NV %du" % len(V))
|
|
w("#define NK %du" % len(K))
|
|
w("#define NP %du" % len(PREDS))
|
|
w('#define BAR() __asm__ volatile("" ::: "memory")')
|
|
w("#define NOI __attribute__((noinline)) static")
|
|
w("static volatile u16 gSink;")
|
|
w("static const u64 kV[NV] = {")
|
|
for i in range(0, len(V), 3):
|
|
w(" " + " ".join("0x%016XULL," % v for v in V[i:i + 3]))
|
|
w("};")
|
|
w("static const u8 kExp[%d] = {" % len(exp))
|
|
for i in range(0, len(exp), 16):
|
|
w(" " + " ".join("0x%02X," % b for b in exp[i:i + 16]))
|
|
w("};")
|
|
for name, t, op in PREDS:
|
|
w("NOI u16 br_%s(u64 a, u64 b) { if ((%s)a %s (%s)b) { BAR(); return 1u; } return 0u; }" % (name, t, op, t))
|
|
w("NOI u16 va_%s(u64 a, u64 b) { return (u16)((%s)a %s (%s)b); }" % (name, t, op, t))
|
|
w("NOI u16 se_%s(u64 a, u64 b) { return (%s)a %s (%s)b ? 0x5A5Au : 0xA5A5u; }" % (name, t, op, t))
|
|
for i, k in enumerate(K):
|
|
w("NOI u16 bk_%s_%d(u64 a) { if ((%s)a %s (%s)0x%016XULL) { BAR(); return 1u; } return 0u; }" % (name, i, t, op, t, k))
|
|
w("NOI u16 vk_%s_%d(u64 a) { return (u16)((%s)a %s (%s)0x%016XULL); }" % (name, i, t, op, t, k))
|
|
w("typedef u16 (*Fn2)(u64, u64);")
|
|
w("typedef u16 (*Fn1)(u64);")
|
|
for p in ("br", "va", "se"):
|
|
w("static Fn2 const k%s[NP] = { %s };" % (p.capitalize(), ", ".join("%s_%s" % (p, n) for n, _, _ in PREDS)))
|
|
for p in ("bk", "vk"):
|
|
w("static Fn1 const k%s[NP * NK] = {" % p.capitalize())
|
|
for n, _, _ in PREDS:
|
|
w(" " + " ".join("%s_%s_%d," % (p, n, i) for i in range(len(K))))
|
|
w("};")
|
|
w("NOI u16 loopUlt(u64 s, u64 e) { u16 n = 0u; u64 i; for (i = s; i < e; i++) { gSink = (u16)i; n++; } return n; }")
|
|
w("NOI u16 loopSge(s64 s, s64 e) { u16 n = 0u; s64 i; for (i = e; i >= s; i--) { gSink = (u16)i; n++; } return n; }")
|
|
w("NOI u16 loopUgtDown(u64 s, u64 e) { u16 n = 0u; u64 i; for (i = e; i > s; i--) { gSink = (u16)i; n++; } return n; }")
|
|
w("static u16 gBad;")
|
|
w("static u16 gFirst = 0xFFFFu;")
|
|
w("static void check(u16 got, u16 want, u16 id) {")
|
|
w(" if (got != want) {")
|
|
w(" if (gBad == 0u) {")
|
|
w(" gFirst = id;")
|
|
w(" }")
|
|
w(" gBad++;")
|
|
w(" }")
|
|
w("}")
|
|
w("int main(void) {")
|
|
w(" u16 p;")
|
|
w(" u16 i;")
|
|
w(" u16 j;")
|
|
w(" u16 bit = 0u;")
|
|
w(" for (p = 0u; p < NP; p++) {")
|
|
w(" for (i = 0u; i < NV; i++) {")
|
|
w(" for (j = 0u; j < NV; j++) {")
|
|
w(" u16 want = (u16)((kExp[bit >> 3] >> (bit & 7u)) & 1u);")
|
|
w(" check(kBr[p](kV[i], kV[j]), want, bit);")
|
|
w(" check(kVa[p](kV[i], kV[j]), want, (u16)(bit | 0x4000u));")
|
|
w(" check(kSe[p](kV[i], kV[j]) == 0x5A5Au, want, (u16)(bit | 0x8000u));")
|
|
w(" bit++;")
|
|
w(" }")
|
|
w(" }")
|
|
w(" }")
|
|
w(" for (p = 0u; p < NP * NK; p++) {")
|
|
w(" for (i = 0u; i < NV; i++) {")
|
|
w(" u16 want = (u16)((kExp[bit >> 3] >> (bit & 7u)) & 1u);")
|
|
w(" check(kBk[p](kV[i]), want, bit);")
|
|
w(" check(kVk[p](kV[i]), want, (u16)(bit | 0x4000u));")
|
|
w(" bit++;")
|
|
w(" }")
|
|
w(" }")
|
|
w(" check(loopUlt(0x00000000FFFFFFF0ULL, 0x0000000100000010ULL), 32u, 0xC000u);")
|
|
w(" check(loopUlt(0x7FFFFFFFFFFFFFF0ULL, 0x8000000000000010ULL), 32u, 0xC001u);")
|
|
w(" check(loopSge(-5LL, 5LL), 11u, 0xC002u);")
|
|
w(" check(loopUgtDown(0x0000FFFFFFFFFFF8ULL, 0x0001000000000008ULL), 16u, 0xC003u);")
|
|
w(" *(volatile u16 *)0x025000UL = gBad;")
|
|
w(" *(volatile u16 *)0x025002UL = gFirst;")
|
|
w(" *(volatile u16 *)0x025004UL = 0xC0DEu;")
|
|
w(" for (;;) {")
|
|
w(" }")
|
|
w(" return 0;")
|
|
w("}")
|
|
print("\n".join(o))
|