diff --git a/src/compiler/ppc/system.lisp b/src/compiler/ppc/system.lisp
index c3fe76a797496ab3443cc7688f873ecc12d3f354..edeed9a7d3a95a592db2a0dcdf817cb080ca1c7a 100644
--- a/src/compiler/ppc/system.lisp
+++ b/src/compiler/ppc/system.lisp
@@ -275,3 +275,22 @@
 
 (defun read-cycle-counter ()
   (read-time-base))
+
+(defmacro with-cycle-counter (&body body)
+  "Returns the primary value of BODY as the primary value, and the
+ number of tick cycles elapsed as secondary value.  To get the number
+ of cycles, multiply by *cycles-per-tick*"
+  (let ((hi0 (gensym))
+	(hi1 (gensym))
+	(lo0 (gensym))
+	(lo1 (gensym)))
+    `(multiple-value-bind (,lo0 ,hi0)
+	 (read-cycle-counter)
+       (values (locally ,@body)
+               (multiple-value-bind (,lo1 ,hi1)
+		   (read-cycle-counter)
+		 ;; Can't do anything about the notes about generic
+		 ;; arithmetic, so silence the notes..
+		 (declare (optimize (inhibit-warnings 3))
+                 (+ (ash (- ,hi1 ,hi0) 32)
+                    (- ,lo1 ,lo0)))))))
diff --git a/src/compiler/sparc/system.lisp b/src/compiler/sparc/system.lisp
index f4f99f94e2c73942a1cfd02e00ebd09fb09dfd71..2ba0b34fcc8fa0ea2c6ef82c97e780d09e822f53 100644
--- a/src/compiler/sparc/system.lisp
+++ b/src/compiler/sparc/system.lisp
@@ -284,3 +284,21 @@
 64-bit counter is returned as two 32-bit unsigned integers.  The low 32-bit
 result is the first value."
   (read-cycle-counter))
+
+(defmacro with-cycle-counter (&body body)
+  "Returns the primary value of BODY as the primary value, and the
+ number of CPU cycles elapsed as secondary value."
+  (let ((hi0 (gensym))
+	(hi1 (gensym))
+	(lo0 (gensym))
+	(lo1 (gensym)))
+    `(multiple-value-bind (,lo0 ,hi0)
+	 (read-cycle-counter)
+       (values (locally ,@body)
+               (multiple-value-bind (,lo1 ,hi1)
+		   (read-cycle-counter)
+		 ;; Can't do anything about the notes about generic
+		 ;; arithmetic, so silence the notes..
+		 (declare (optimize (inhibit-warnings 3))
+                 (+ (ash (- ,hi1 ,hi0) 32)
+                    (- ,lo1 ,lo0)))))))
diff --git a/src/compiler/x86/system.lisp b/src/compiler/x86/system.lisp
index bb323326e7218bb47359eb77957f109d37961fad..9207b5b020178656060095ad6d6317d436faf2ce 100644
--- a/src/compiler/x86/system.lisp
+++ b/src/compiler/x86/system.lisp
@@ -562,7 +562,7 @@
     (inst ret)))
 
 
-;; the RDTSC instruction (present on Pentium processors and
+;; The RDTSC instruction (present on Pentium processors and
 ;; successors) allows you to access the time-stamp counter, a 64-bit
 ;; model-specific register that counts executed cycles. The
 ;; instruction returns the low cycle count in EAX and high cycle count
@@ -676,3 +676,21 @@
 (defun cpuid (level)
   (declare (type (unsigned-byte 32) level))
   (cpuid level))
+
+(defmacro with-cycle-counter (&body body)
+  "Returns the primary value of BODY as the primary value, and the
+ number of CPU cycles elapsed as secondary value."
+  (let ((hi0 (gensym))
+	(hi1 (gensym))
+	(lo0 (gensym))
+	(lo1 (gensym)))
+    `(multiple-value-bind (,lo0 ,hi0)
+	 (read-cycle-counter)
+       (values (locally ,@body)
+               (multiple-value-bind (,lo1 ,hi1)
+		   (read-cycle-counter)
+		 ;; Can't do anything about the notes about generic
+		 ;; arithmetic, so silence the notes..
+		 (declare (optimize (inhibit-warnings 3))
+                 (+ (ash (- ,hi1 ,hi0) 32)
+                    (- ,lo1 ,lo0)))))))
diff --git a/src/general-info/release-20d.txt b/src/general-info/release-20d.txt
index c11c5ee3b9c823693be26e1df8b5c5f64e233901..a17c0da3504dc7ac4c3dd027433e91179d5e6755 100644
--- a/src/general-info/release-20d.txt
+++ b/src/general-info/release-20d.txt
@@ -54,6 +54,8 @@ New in this release:
     * OSX 10.4 is no longer supported.
     * Micro optimizations for floats: 2*x -> x+x and x/2^n ->
       (2^(n))*x.
+    * Add VM::WITH-CYCLE-COUNTER to return the number of cycles elapsed
+      when executing the body, as measured by the CPU cycle/tick counter.
 
   * ANSI compliance fixes:
     * CMUCL was not printing pathnames like (make-pathname :directory