--- a/src/compiler/mips/insts.lisp
+++ b/src/compiler/mips/insts.lisp
@@ -58,8 +58,7 @@
        (:hi-reg 64)
        (:low-reg 65)
        (:float-status 66)
-       (:ctrl-stat-reg 67)
-       (:r31 31)))))
+       (:ctrl-stat-reg 67)))))
 
 (defparameter reg-symbols
   (map 'vector
@@ -670,7 +669,7 @@
                        (immediate nil :type 'relative-label))
             '(:name :tab immediate))
   (:attributes branch)
-  (:dependencies (writes :r31))
+  (:dependencies (writes lip-tn))
   (:delay 1)
   (:emitter
    (emit-relative-branch segment bcond-op 0 #b10001 target)))
@@ -757,7 +756,7 @@
    immediate ((op bcond-op) (rt #b01000) (immediate nil :type 'relative-label))
             cond-branch-printer)
   (:attributes branch)
-  (:dependencies (reads reg) (writes :r31))
+  (:dependencies (reads reg) (writes lip-tn))
   (:delay 1)
   (:emitter
    (emit-relative-branch segment bcond-op reg #b10000 target)))
@@ -769,7 +768,7 @@
             cond-branch-printer)
   (:attributes branch)
   (:delay 1)
-  (:dependencies (reads reg) (writes :r31))
+  (:dependencies (reads reg) (writes lip-tn))
   (:emitter
    (emit-relative-branch segment bcond-op reg #b10001 target)))
 
@@ -791,28 +790,41 @@
       (emit-register-inst segment special-op (reg-tn-encoding target)
                           0 0 0 #b001000))
      (fixup
-      (note-fixup segment :jump target)
-      (emit-jump-inst segment #b000010 0)))))
+      (note-fixup segment :lui target)
+      (emit-immediate-inst segment #b001111 0 28 0)
+      (note-fixup segment :addi target)
+      (emit-immediate-inst segment #b001001 28 28 0)
+      (emit-register-inst segment special-op 28 0 0 0 #b001000)))))
 
 (define-instruction jal (segment reg-or-target &optional target)
   (:declare (type (or null tn fixup) target)
-            (type (or tn fixup (integer -16 31)) reg-or-target))
+            (type (or tn fixup) reg-or-target))
   (:printer register ((op special-op) (rt 0) (funct #b001001)) j-printer)
   (:printer jump ((op #b000011)) j-printer)
   (:attributes branch)
-  (:dependencies (if target (writes reg-or-target) (writes :r31)))
+  (:dependencies (cond
+                   (target
+                    (writes reg-or-target) (reads target))
+                   (t
+                    (writes lip-tn)
+                    (when (tn-p reg-or-target)
+                      (reads reg-or-target)))))
   (:delay 1)
   (:emitter
    (unless target
-     (setf target reg-or-target)
-     (setf reg-or-target 31))
+     (setf target reg-or-target
+           reg-or-target lip-tn))
    (etypecase target
      (tn
       (emit-register-inst segment special-op (reg-tn-encoding target) 0
-                          reg-or-target 0 #b001001))
+                          (reg-tn-encoding reg-or-target) 0 #b001001))
      (fixup
-      (note-fixup segment :jump target)
-      (emit-jump-inst segment #b000011 0)))))
+      (note-fixup segment :lui target)
+      (emit-immediate-inst segment #b001111 0 28 0)
+      (note-fixup segment :addi target)
+      (emit-immediate-inst segment #b001001 28 28 0)
+      (emit-register-inst segment special-op 28 0
+                          (reg-tn-encoding reg-or-target) 0 #b001001)))))
 
 (define-instruction bc1f (segment target)
   (:declare (type label target))