diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5fe02861f3708b0f2ce82ad883d7cf54bec56cc3..793d9d0f21f1fbd28c5a808be5310bfbdbaeace4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,7 @@
 Tue Jun 29 01:37:53 1999  Jeffrey A Law  (law@cygnus.com)
 
+	* mips.md (leasi, leadi): New patterns.
+
 	* expr.c (emit_block_move): Properly handle case where one of the
 	block move arguments has a queued increment or decrement.
 	(clear_storage): Similarly.  Fix formatting goof.
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index fb739b8566974244a3030c2009780b3524443d0d..c3a6ba7068c5e36d84488fd059ce2baeadd9fbaa 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -10395,3 +10395,27 @@ move\\t%0,%z4\\n\\
   [(set_attr "type"	"branch")
    (set_attr "mode"	"none")
    (set_attr "length"	"8")])
+
+;; For the rare case where we need to load an address into a register
+;; that can not be recognized by the normal movsi/addsi instructions.
+;; I have no idea how many insns this can actually generate.  It should
+;; be rare, so over-estimating as 10 instructions should not have any
+;; real performance impact.
+(define_insn "leasi"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (match_operand:SI 1 "address_operand" "p"))]
+  "Pmode == SImode"
+  "la %0,%a1"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"SI")
+   (set_attr "length"	"40")])
+
+;; Similarly for targets where we have 64bit pointers.
+(define_insn "leadi"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+        (match_operand:DI 1 "address_operand" "p"))]
+  "Pmode == DImode"
+  "la %0,%a1"
+  [(set_attr "type"	"arith")
+   (set_attr "mode"	"DI")
+   (set_attr "length"	"40")])