[DTrace-devel] [PATCH 21/61] Promote integers to 64 bits when loaded
eugene.loh at oracle.com
eugene.loh at oracle.com
Fri Jul 8 14:45:05 UTC 2022
From: Eugene Loh <eugene.loh at oracle.com>
DTrace internally implements integers with 64-bit registers. This
makes the manipulation of integers of different sizes simpler, by
avoiding a number of typecast operations. But DTrace has also
loaded integers without promoting them appropriately. E.g.,
((short)0xffff) has been treated as 0xffff rather than -1.
Promote integers to 64 bits when loading.
Add tests. Specifically, typecasting should typically not be needed.
Therefore, operations such as x=y and x+y (of different types) should
work properly if integers are correctly represented in 64-bit registers.
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_cg.c | 16 +++++
test/unittest/arithmetic/tst.cast-add.d | 88 +++++++++++++++++++++++
test/unittest/arithmetic/tst.cast-add.r | 37 ++++++++++
test/unittest/arithmetic/tst.cast-imp.d | 95 +++++++++++++++++++++++++
test/unittest/arithmetic/tst.cast-imp.r | 43 +++++++++++
5 files changed, 279 insertions(+)
create mode 100644 test/unittest/arithmetic/tst.cast-add.d
create mode 100644 test/unittest/arithmetic/tst.cast-add.r
create mode 100644 test/unittest/arithmetic/tst.cast-imp.d
create mode 100644 test/unittest/arithmetic/tst.cast-imp.r
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index f1893198..9b47dc02 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -2192,6 +2192,20 @@ dt_cg_load(dt_node_t *dnp, ctf_file_t *ctfp, ctf_id_t type, ssize_t *ret_size)
#endif
}
+/*
+ * Generate code for typecast and promotion to 64 bits.
+ */
+static void
+dt_cg_typecast_64(const dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ int n = sizeof(uint64_t) * NBBY - dt_node_type_size(dnp) * NBBY;
+
+ if (n == 0)
+ return;
+ emit(dlp, BPF_ALU64_IMM(BPF_LSH, dnp->dn_reg, n));
+ emit(dlp, BPF_ALU64_IMM((dnp->dn_flags & DT_NF_SIGNED) ? BPF_ARSH : BPF_RSH, dnp->dn_reg, n));
+}
+
static void
dt_cg_load_var(dt_node_t *dst, dt_irlist_t *dlp, dt_regset_t *drp)
{
@@ -2224,6 +2238,7 @@ dt_cg_load_var(dt_node_t *dst, dt_irlist_t *dlp, dt_regset_t *drp)
(size & (size - 1)) == 0);
emit(dlp, BPF_LOAD(ldstw[size], dst->dn_reg, dst->dn_reg, idp->di_offset));
+ dt_cg_typecast_64(dst, dlp, drp);
}
return;
@@ -2264,6 +2279,7 @@ dt_cg_load_var(dt_node_t *dst, dt_irlist_t *dlp, dt_regset_t *drp)
emit(dlp, BPF_JUMP(lbl_done));
emitl(dlp, lbl_notnull,
BPF_LOAD(ldstw[size], dst->dn_reg, BPF_REG_0, 0));
+ dt_cg_typecast_64(dst, dlp, drp);
dt_regset_free(drp, BPF_REG_0);
emitl(dlp, lbl_done,
diff --git a/test/unittest/arithmetic/tst.cast-add.d b/test/unittest/arithmetic/tst.cast-add.d
new file mode 100644
index 00000000..7905fa33
--- /dev/null
+++ b/test/unittest/arithmetic/tst.cast-add.d
@@ -0,0 +1,88 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/*
+ * ASSERTION: Integers are promoted correctly for mixed-type adds.
+ * Compare results to a similar C program,
+ * albeit with the format strings
+ * "%hhd", "%hd", "%d", "%lld", "%hhu", "%hu", "%u", "%llu".
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ */
+/* @@runtest-opts: -qC */
+
+char c;
+short s;
+int i;
+long long l;
+unsigned char C;
+unsigned short S;
+unsigned int I;
+unsigned long long L;
+
+#define TEST(x, y, fmt) \
+ x = -2; y = -3; printf(fmt, x + y); printf(fmt, y + x); \
+ x = -2; y = +3; printf(fmt, x + y); printf(fmt, y + x); \
+ x = +2; y = -3; printf(fmt, x + y); printf(fmt, y + x); \
+ x = +2; y = +3; printf(fmt, x + y); printf(fmt, y + x); printf("\n");
+
+BEGIN
+{
+ /* cast to char (C conversion %hhd) */
+ TEST(c, c, " %d")
+
+ /* cast to unsigned char (C conversion %hhu) */
+ TEST(C, c, " %d")
+ TEST(C, C, " %d")
+
+ /* cast to short (C conversion %hd) */
+ TEST(s, c, " %d")
+ TEST(s, C, " %d")
+ TEST(s, s, " %d")
+
+ /* cast to unsigned short (C conversion %hu) */
+ TEST(S, c, " %d")
+ TEST(S, C, " %d")
+ TEST(S, s, " %d")
+ TEST(S, S, " %d")
+
+ /* cast to int (C conversion %d) */
+ TEST(i, c, " %d")
+ TEST(i, C, " %d")
+ TEST(i, s, " %d")
+ TEST(i, S, " %d")
+ TEST(i, i, " %d")
+
+ /* cast to unsigned int (C conversion %u) */
+ TEST(I, c, " %d")
+ TEST(I, C, " %d")
+ TEST(I, s, " %d")
+ TEST(I, S, " %d")
+ TEST(I, i, " %d")
+ TEST(I, I, " %d")
+
+ /* cast to long long (C conversion %lld) */
+ TEST(l, c, " %d")
+ TEST(l, C, " %d")
+ TEST(l, s, " %d")
+ TEST(l, S, " %d")
+ TEST(l, i, " %d")
+ TEST(l, I, " %d")
+ TEST(l, l, " %d")
+
+ /* cast to unsigned long long (C conversion %llu) */
+ TEST(L, c, " %d")
+ TEST(L, C, " %d")
+ TEST(L, s, " %d")
+ TEST(L, S, " %d")
+ TEST(L, i, " %d")
+ TEST(L, I, " %d")
+ TEST(L, l, " %d")
+ TEST(L, L, " %d")
+
+ exit (0);
+}
diff --git a/test/unittest/arithmetic/tst.cast-add.r b/test/unittest/arithmetic/tst.cast-add.r
new file mode 100644
index 00000000..778b88e0
--- /dev/null
+++ b/test/unittest/arithmetic/tst.cast-add.r
@@ -0,0 +1,37 @@
+ -6 -6 6 6 -6 -6 6 6
+ 251 251 1 1 255 255 5 5
+ 250 250 6 6 250 250 6 6
+ -5 -5 1 1 -1 -1 5 5
+ 251 251 1 1 255 255 5 5
+ -6 -6 6 6 -6 -6 6 6
+ 65531 65531 1 1 65535 65535 5 5
+ 251 251 1 1 255 255 5 5
+ 65531 65531 1 1 65535 65535 5 5
+ 65530 65530 6 6 65530 65530 6 6
+ -5 -5 1 1 -1 -1 5 5
+ 251 251 1 1 255 255 5 5
+ -5 -5 1 1 -1 -1 5 5
+ 65531 65531 1 1 65535 65535 5 5
+ -6 -6 6 6 -6 -6 6 6
+ 4294967291 4294967291 1 1 4294967295 4294967295 5 5
+ 251 251 1 1 255 255 5 5
+ 4294967291 4294967291 1 1 4294967295 4294967295 5 5
+ 65531 65531 1 1 65535 65535 5 5
+ 4294967291 4294967291 1 1 4294967295 4294967295 5 5
+ 4294967290 4294967290 6 6 4294967290 4294967290 6 6
+ -5 -5 1 1 -1 -1 5 5
+ 251 251 1 1 255 255 5 5
+ -5 -5 1 1 -1 -1 5 5
+ 65531 65531 1 1 65535 65535 5 5
+ -5 -5 1 1 -1 -1 5 5
+ 4294967291 4294967291 1 1 4294967295 4294967295 5 5
+ -6 -6 6 6 -6 -6 6 6
+ 18446744073709551611 18446744073709551611 1 1 18446744073709551615 18446744073709551615 5 5
+ 251 251 1 1 255 255 5 5
+ 18446744073709551611 18446744073709551611 1 1 18446744073709551615 18446744073709551615 5 5
+ 65531 65531 1 1 65535 65535 5 5
+ 18446744073709551611 18446744073709551611 1 1 18446744073709551615 18446744073709551615 5 5
+ 4294967291 4294967291 1 1 4294967295 4294967295 5 5
+ 18446744073709551611 18446744073709551611 1 1 18446744073709551615 18446744073709551615 5 5
+ 18446744073709551610 18446744073709551610 6 6 18446744073709551610 18446744073709551610 6 6
+
diff --git a/test/unittest/arithmetic/tst.cast-imp.d b/test/unittest/arithmetic/tst.cast-imp.d
new file mode 100644
index 00000000..9bda57bc
--- /dev/null
+++ b/test/unittest/arithmetic/tst.cast-imp.d
@@ -0,0 +1,95 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/*
+ * ASSERTION: Integers are typecast correctly. (implicit)
+ * Compare results to a similar C program,
+ * albeit with the format string
+ * "%hhd %hd %d %lld %hhu %hu %u %llu\n".
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ */
+/* @@runtest-opts: -qC */
+
+char c;
+short s;
+int i;
+long long l;
+unsigned char C;
+unsigned short S;
+unsigned int I;
+unsigned long long L;
+
+#define TEST(x) \
+ c = (x); s = (x); i = (x); l = (x); \
+ C = (x); S = (x); I = (x); L = (x); \
+ printf("%d %d %d %d %d %d %d %d\n", c, s, i, l, C, S, I, L)
+
+BEGIN
+{
+ /* from scalar */
+ TEST(-2);
+ TEST(0xfffffffffffffffe);
+ TEST(0xfffffffe);
+ TEST(0xfffe);
+ TEST(0xfe);
+ TEST(2);
+ TEST(0x55);
+ TEST(0x5555);
+ TEST(0x55555555);
+ TEST(0x5555555555555555);
+
+ /* from char */
+ c = -2; TEST(c);
+ c = 0xfe; TEST(c);
+ c = 2; TEST(c);
+ c = 0x55; TEST(c);
+
+ /* from short */
+ s = -2; TEST(s);
+ s = 0xfffe; TEST(s);
+ s = 2; TEST(s);
+ s = 0x5555; TEST(s);
+
+ /* from int */
+ i = -2; TEST(i);
+ i = 0xfffffffe; TEST(i);
+ i = 2; TEST(i);
+ i = 0x55555555; TEST(i);
+
+ /* from long long */
+ l = -2; TEST(l);
+ l = 0xfffffffffffffffe; TEST(l);
+ l = 2; TEST(l);
+ l = 0x5555555555555555; TEST(l);
+
+ /* from unsigned char */
+ C = -2; TEST(C);
+ C = 0xfe; TEST(C);
+ C = 2; TEST(C);
+ C = 0x55; TEST(C);
+
+ /* from unsigned short */
+ S = -2; TEST(S);
+ S = 0xfffe; TEST(S);
+ S = 2; TEST(S);
+ S = 0x5555; TEST(S);
+
+ /* from unsigned int */
+ I = -2; TEST(I);
+ I = 0xfffffffe; TEST(I);
+ I = 2; TEST(I);
+ I = 0x55555555; TEST(I);
+
+ /* from unsigned long long */
+ L = -2; TEST(L);
+ L = 0xfffffffffffffffe; TEST(L);
+ L = 2; TEST(L);
+ L = 0x5555555555555555; TEST(L);
+
+ exit (0);
+}
diff --git a/test/unittest/arithmetic/tst.cast-imp.r b/test/unittest/arithmetic/tst.cast-imp.r
new file mode 100644
index 00000000..0ae3e3f1
--- /dev/null
+++ b/test/unittest/arithmetic/tst.cast-imp.r
@@ -0,0 +1,43 @@
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+-2 -2 -2 4294967294 254 65534 4294967294 4294967294
+-2 -2 65534 65534 254 65534 65534 65534
+-2 254 254 254 254 254 254 254
+2 2 2 2 2 2 2 2
+85 85 85 85 85 85 85 85
+85 21845 21845 21845 85 21845 21845 21845
+85 21845 1431655765 1431655765 85 21845 1431655765 1431655765
+85 21845 1431655765 6148914691236517205 85 21845 1431655765 6148914691236517205
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+2 2 2 2 2 2 2 2
+85 85 85 85 85 85 85 85
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+2 2 2 2 2 2 2 2
+85 21845 21845 21845 85 21845 21845 21845
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+2 2 2 2 2 2 2 2
+85 21845 1431655765 1431655765 85 21845 1431655765 1431655765
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+2 2 2 2 2 2 2 2
+85 21845 1431655765 6148914691236517205 85 21845 1431655765 6148914691236517205
+-2 254 254 254 254 254 254 254
+-2 254 254 254 254 254 254 254
+2 2 2 2 2 2 2 2
+85 85 85 85 85 85 85 85
+-2 -2 65534 65534 254 65534 65534 65534
+-2 -2 65534 65534 254 65534 65534 65534
+2 2 2 2 2 2 2 2
+85 21845 21845 21845 85 21845 21845 21845
+-2 -2 -2 4294967294 254 65534 4294967294 4294967294
+-2 -2 -2 4294967294 254 65534 4294967294 4294967294
+2 2 2 2 2 2 2 2
+85 21845 1431655765 1431655765 85 21845 1431655765 1431655765
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+-2 -2 -2 -2 254 65534 4294967294 18446744073709551614
+2 2 2 2 2 2 2 2
+85 21845 1431655765 6148914691236517205 85 21845 1431655765 6148914691236517205
+
--
2.18.4
More information about the DTrace-devel
mailing list