diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index 94d8794bd23..d0630a1998f 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -183,10 +183,18 @@ kmacro-keymap
   "C-l"  #'kmacro-call-ring-2nd-repeat
 
   ;; macro counter
-  "C-f"  #'kmacro-set-format
-  "C-c"  #'kmacro-set-counter
-  "C-i"  #'kmacro-insert-counter
-  "C-a"  #'kmacro-add-counter
+  "C-f"     #'kmacro-set-format
+  "C-c"     #'kmacro-set-counter
+  "C-i"     #'kmacro-insert-counter
+  "C-a"     #'kmacro-add-counter
+  "C-r l"   #'kmacro-reg-load-counter
+  "C-r s"   #'kmacro-reg-save-counter
+  "C-r a =" #'kmacro-reg-add-counter-equal
+  "C-r a <" #'kmacro-reg-add-counter-less
+  "C-r a >" #'kmacro-reg-add-counter-greater
+  "C-q ="   #'kmacro-quit-counter-equal
+  "C-q <"   #'kmacro-quit-counter-less
+  "C-q >"   #'kmacro-quit-counter-greater
 
   ;; macro editing
   "C-e"  #'kmacro-edit-macro-repeat
@@ -347,6 +355,96 @@ kmacro-add-counter
     (kmacro-display-counter)))
 
 
+(defun kmacro-reg-load-counter (register)
+  "Load the value of REGISTER into `kmacro-counter'."
+  (interactive
+   (list (register-read-with-preview "Load register to counter: ")))
+  (let ((register-val (get-register register)))
+    (when (numberp register-val)
+     (setq kmacro-counter register-val))))
+
+
+(defun kmacro-reg-save-counter (register)
+  "Save the value of `kmacro-counter' to REGISTER."
+  (interactive
+   (list (register-read-with-preview "Save counter to register: ")))
+  (set-register register kmacro-counter))
+
+
+(defun kmacro-reg-add-counter-equal (&optional arg)
+  "Increment `kmacro-counter' by ARG if the counter is equal to a
+register's value.
+ARG is the numeric prefix argument that defaults to one."
+  (interactive "p")
+  (let
+      ((register (register-read-with-preview "Compare counter to register: ")))
+    (kmacro-reg-add-counter '= register arg)))
+
+
+(defun kmacro-reg-add-counter-less (&optional arg)
+  "Increment `kmacro-counter' by ARG if the counter is less than a
+register's value.
+ARG is the numeric prefix argument that defaults to one."
+  (interactive "p")
+  (let
+      ((register (register-read-with-preview "Compare counter to register: ")))
+    (kmacro-reg-add-counter '< register arg)))
+
+
+(defun kmacro-reg-add-counter-greater (&optional arg)
+  "Increment `kmacro-counter' by ARG if the counter is greater than
+a register's value.
+ARG is the numeric prefix argument that defaults to one."
+  (interactive "p")
+  (let
+      ((register (register-read-with-preview "Compare counter to register: ")))
+    (kmacro-reg-add-counter '> register arg)))
+
+
+(defun kmacro-reg-add-counter (pred register arg)
+  "Increment `kmacro-counter' by ARG if predicate PRED returns
+non-nil.
+PRED is called with two arguments: `kmacro-counter' and REGISTER."
+  (let ((register-val (get-register register)))
+    (when (apply pred (list kmacro-counter register-val))
+      (setq current-prefix-arg nil)
+      (kmacro-add-counter arg))))
+
+
+(defun kmacro-quit-counter-equal (&optional arg)
+  "Quit the keyboard macro if `kmacro-counter' is equal to ARG.
+ARG is the numeric prefix argument that defaults to zero."
+  (interactive "P")
+  (kmacro-quit-counter '= arg))
+
+
+(defun kmacro-quit-counter-less (&optional arg)
+  "Quit the keyboard macro if `kmacro-counter' is less than ARG.
+ARG is the numeric prefix argument that defaults to zero."
+  (interactive "P")
+  (kmacro-quit-counter '< arg))
+
+
+(defun kmacro-quit-counter-greater (&optional arg)
+  "Quit the keyboard macro if `kmacro-counter' is greater than ARG.
+ARG is the numeric prefix argument that defaults to zero."
+    (interactive "P")
+    (kmacro-quit-counter '> arg))
+
+
+(defun kmacro-quit-counter (pred &optional arg)
+  "Quit the keyboard macro if predicate PRED returns non-nil.
+PRED is called with two arguments: `kmacro-counter' and ARG."
+  (when kmacro-initial-counter-value
+    (setq kmacro-counter kmacro-initial-counter-value
+	  kmacro-initial-counter-value nil))
+  (let ((arg
+	 (cond ((null arg) 0)
+	       (t (prefix-numeric-value arg)))))
+    (when (apply pred (list kmacro-counter arg))
+      (keyboard-quit))))
+
+
 (defun kmacro-loop-setup-function ()
   "Function called prior to each iteration of macro."
   ;; Restore macro counter format to initial format, so it is ok to change
