[DTrace-devel] [PATCH v3 21/61] Promote integers to 64 bits when loaded

eugene.loh at oracle.com eugene.loh at oracle.com
Wed Aug 3 23:12:10 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 | 116 ++++++++++++++++++++++++
 test/unittest/arithmetic/tst.cast-add.r |  37 ++++++++
 test/unittest/arithmetic/tst.cast-imp.d | 112 +++++++++++++++++++++++
 test/unittest/arithmetic/tst.cast-imp.r |  43 +++++++++
 5 files changed, 324 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 4dc939fb..f77e239b 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -2144,6 +2144,20 @@ dt_cg_ldsize(dt_node_t *dnp, ctf_file_t *ctfp, ctf_id_t type, ssize_t *ret_size)
 	return ldstw[size];
 }
 
+/*
+ * 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)
 {
@@ -2176,6 +2190,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;
@@ -2216,6 +2231,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..c3a4d90d
--- /dev/null
+++ b/test/unittest/arithmetic/tst.cast-add.d
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ *	       The .r results file can be generated by copying this file
+ *	       to a .c file and compiling the resulting C program.
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ */
+/* @@runtest-opts: -qC -DUSE_AS_D_SCRIPT */
+
+#ifndef USE_AS_D_SCRIPT
+#include <stdio.h>
+#endif
+
+signed char c;
+short s;
+int i;
+long long l;
+unsigned char C;
+unsigned short S;
+unsigned int I;
+unsigned long long L;
+
+#ifdef USE_AS_D_SCRIPT
+#define FMT " %d"
+#define USE_FMT(f)
+#else
+char *fmt;
+#define FMT fmt
+#define USE_FMT(f) fmt = f;
+#endif
+
+#define TEST(x, y) \
+  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");
+
+#ifdef USE_AS_D_SCRIPT
+BEGIN
+#else
+int main(int c_unused, char *v_unused)
+#endif
+{
+	/* cast to signed char */
+	USE_FMT(" %hhd");
+	TEST(c, c)
+
+	/* cast to unsigned char */
+	USE_FMT(" %hhu");
+	TEST(C, c)
+	TEST(C, C)
+
+	/* cast to short */
+	USE_FMT(" %hd");
+	TEST(s, c)
+	TEST(s, C)
+	TEST(s, s)
+
+	/* cast to unsigned short */
+	USE_FMT(" %hu");
+	TEST(S, c)
+	TEST(S, C)
+	TEST(S, s)
+	TEST(S, S)
+
+	/* cast to int */
+	USE_FMT(" %d");
+	TEST(i, c)
+	TEST(i, C)
+	TEST(i, s)
+	TEST(i, S)
+	TEST(i, i)
+
+	/* cast to unsigned int */
+	USE_FMT(" %u");
+	TEST(I, c)
+	TEST(I, C)
+	TEST(I, s)
+	TEST(I, S)
+	TEST(I, i)
+	TEST(I, I)
+
+	/* cast to long long */
+	USE_FMT(" %lld");
+	TEST(l, c)
+	TEST(l, C)
+	TEST(l, s)
+	TEST(l, S)
+	TEST(l, i)
+	TEST(l, I)
+	TEST(l, l)
+
+	/* cast to unsigned long long */
+	USE_FMT(" %llu");
+	TEST(L, c)
+	TEST(L, C)
+	TEST(L, s)
+	TEST(L, S)
+	TEST(L, i)
+	TEST(L, I)
+	TEST(L, l)
+	TEST(L, L)
+
+#ifdef USE_AS_D_SCRIPT
+	exit (0);
+#else
+	return 0;
+#endif
+}
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..dbce9893
--- /dev/null
+++ b/test/unittest/arithmetic/tst.cast-imp.d
@@ -0,0 +1,112 @@
+/*
+ * 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)
+ *	       The .r results file can be generated by copying this file
+ *	       to a .c file and compiling the resulting C program.
+ *
+ * SECTION: Types, Operators, and Expressions/Arithmetic Operators
+ */
+/* @@runtest-opts: -qC -DUSE_AS_D_SCRIPT */
+
+#ifndef USE_AS_D_SCRIPT
+#include <stdio.h>
+#endif
+
+signed char c, c0;
+short s, s0;
+int i, i0;
+long long l, l0;
+unsigned char C, C0;
+unsigned short S, S0;
+unsigned int I, I0;
+unsigned long long L, L0;
+
+#ifdef USE_AS_D_SCRIPT
+#define FMT "%d %d %d %d %d %d %d %d\n"
+#else
+#define FMT "%hhd %hd %d %lld %hhu %hu %u %llu\n"
+#endif
+
+#define TEST(x) \
+	c = (x); s = (x); i = (x); l = (x); \
+	C = (x); S = (x); I = (x); L = (x); \
+	printf(FMT, c, s, i, l, C, S, I, L)
+
+#ifdef USE_AS_D_SCRIPT
+BEGIN
+#else
+int main(int c_unused, char **v_unused)
+#endif
+{
+	/* from scalar */
+	TEST(-2);
+	TEST(0xfffffffffffffffe);
+	TEST(0xfffffffe);
+	TEST(0xfffe);
+	TEST(0xfe);
+	TEST(2);
+	TEST(0x55);
+	TEST(0x5555);
+	TEST(0x55555555);
+	TEST(0x5555555555555555);
+
+	/* from signed char */
+	c0 = -2; TEST(c0);
+	c0 = 0xfe; TEST(c0);
+	c0 = 2; TEST(c0);
+	c0 = 0x55; TEST(c0);
+
+	/* from short */
+	s0 = -2; TEST(s0);
+	s0 = 0xfffe; TEST(s0);
+	s0 = 2; TEST(s0);
+	s0 = 0x5555; TEST(s0);
+
+	/* from int */
+	i0 = -2; TEST(i0);
+	i0 = 0xfffffffe; TEST(i0);
+	i0 = 2; TEST(i0);
+	i0 = 0x55555555; TEST(i0);
+
+	/* from long long */
+	l0 = -2; TEST(l0);
+	l0 = 0xfffffffffffffffe; TEST(l0);
+	l0 = 2; TEST(l0);
+	l0 = 0x5555555555555555; TEST(l0);
+
+	/* from unsigned char */
+	C0 = -2; TEST(C0);
+	C0 = 0xfe; TEST(C0);
+	C0 = 2; TEST(C0);
+	C0 = 0x55; TEST(C0);
+
+	/* from unsigned short */
+	S0 = -2; TEST(S0);
+	S0 = 0xfffe; TEST(S0);
+	S0 = 2; TEST(S0);
+	S0 = 0x5555; TEST(S0);
+
+	/* from unsigned int */
+	I0 = -2; TEST(I0);
+	I0 = 0xfffffffe; TEST(I0);
+	I0 = 2; TEST(I0);
+	I0 = 0x55555555; TEST(I0);
+
+	/* from unsigned long long */
+	L0 = -2; TEST(L0);
+	L0 = 0xfffffffffffffffe; TEST(L0);
+	L0 = 2; TEST(L0);
+	L0 = 0x5555555555555555; TEST(L0);
+
+#ifdef USE_AS_D_SCRIPT
+	exit (0);
+#else
+	return 0;
+#endif
+}
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