diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 70fc324985d..8cf9a6c9cad 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* riscv-tdep.c (riscv_insn::decode): Decode c.lui.
+	(riscv_scan_prologue): Split handling of AUIPC, LUI, ADD, ADDI,
+	and NOP.
+
 2018-09-26  Simon Marchi  <simon.marchi@ericsson.com>
 
 	* elf32-nds32.c (elf32_nds32_allocate_dynrelocs): Remove.
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 254914c9c7e..163c8ec231d 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1227,7 +1227,11 @@ riscv_insn::decode (struct gdbarch *gdbarch, CORE_ADDR pc)
 	  m_imm.s = EXTRACT_RVC_ADDI4SPN_IMM (ival);
 	}
       else if (is_c_lui_insn (ival))
-	m_opcode = OTHER;
+        {
+          m_opcode = LUI;
+          m_rd = decode_register_index (ival, OP_SH_CRS1S);
+          m_imm.s = EXTRACT_RVC_LUI_IMM (ival);
+        }
       /* C_SD and C_FSW have the same opcode.  C_SD is RV64 and RV128 only,
 	 and C_FSW is RV32 only.  */
       else if (xlen != 4 && is_c_sd_insn (ival))
@@ -1359,28 +1363,41 @@ riscv_scan_prologue (struct gdbarch *gdbarch,
           gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
           regs[insn.rd ()] = pv_add_constant (regs[insn.rs1 ()], 0);
 	}
-      else if ((insn.rd () == RISCV_GP_REGNUM
-		&& (insn.opcode () == riscv_insn::AUIPC
-		    || insn.opcode () == riscv_insn::LUI
-		    || (insn.opcode () == riscv_insn::ADDI
-			&& insn.rs1 () == RISCV_GP_REGNUM)
-		    || (insn.opcode () == riscv_insn::ADD
-			&& (insn.rs1 () == RISCV_GP_REGNUM
-			    || insn.rs2 () == RISCV_GP_REGNUM))))
-	       || (insn.opcode () == riscv_insn::ADDI
-		   && insn.rd () == RISCV_ZERO_REGNUM
-		   && insn.rs1 () == RISCV_ZERO_REGNUM
-		   && insn.imm_signed () == 0))
+      else if ((insn.opcode () == riscv_insn::ADDI
+                && insn.rd () == RISCV_ZERO_REGNUM
+                && insn.rs1 () == RISCV_ZERO_REGNUM
+                && insn.imm_signed () == 0))
 	{
-	  /* Handle: auipc gp, n
-	     or:     addi gp, gp, n
-	     or:     add gp, gp, reg
-	     or:     add gp, reg, gp
-	     or:     lui gp, n
-	     or:     add x0, x0, 0   (NOP)  */
-	  /* These instructions are part of the prologue, but we don't need
-	     to do anything special to handle them.  */
+	  /* Handle: add x0, x0, 0   (NOP)  */
 	}
+      else if (insn.opcode () == riscv_insn::AUIPC)
+        {
+          gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
+          regs[insn.rd ()] = pv_constant (cur_pc + insn.imm_signed ());
+        }
+      else if (insn.opcode () == riscv_insn::LUI)
+        {
+	  /* Handle: lui REG, n
+             Where REG is not gp register.  */
+          gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
+          regs[insn.rd ()] = pv_constant (insn.imm_signed ());
+        }
+      else if (insn.opcode () == riscv_insn::ADDI)
+        {
+          /* Handle: addi REG1, REG2, IMM  */
+          gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
+          gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
+          regs[insn.rd ()]
+            = pv_add_constant (regs[insn.rs1 ()], insn.imm_signed ());
+        }
+      else if (insn.opcode () == riscv_insn::ADD)
+        {
+          /* Handle: addi REG1, REG2, IMM  */
+          gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
+          gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
+          gdb_assert (insn.rs2 () < RISCV_NUM_INTEGER_REGS);
+          regs[insn.rd ()] = pv_add (regs[insn.rs1 ()], regs[insn.rs2 ()]);
+        }
       else
 	{
 	  end_prologue_addr = cur_pc;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index d15fcff17bd..2b4b0973ef2 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2018-09-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* gdb.base/large-frame-1.c: New file.
+	* gdb.base/large-frame-2.c: New file.
+	* gdb.base/large-frame.exp: New file.
+	* gdb.base/large-frame.h: New file.
+
 2018-09-24  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
 	PR gdb/20948
diff --git a/gdb/testsuite/gdb.base/large-frame-1.c b/gdb/testsuite/gdb.base/large-frame-1.c
new file mode 100644
index 00000000000..cd9c5ccdd0a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/large-frame-1.c
@@ -0,0 +1,32 @@
+/* This file is part of GDB, the GNU debugger.
+
+   Copyright 2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "large-frame.h"
+
+__attribute__ ((noinline)) void
+blah (int *a)
+{
+  asm ("" :: "m" (a) : "memory");
+}
+
+int
+main ()
+{
+  func ();
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/large-frame-2.c b/gdb/testsuite/gdb.base/large-frame-2.c
new file mode 100644
index 00000000000..2491c347292
--- /dev/null
+++ b/gdb/testsuite/gdb.base/large-frame-2.c
@@ -0,0 +1,25 @@
+/* This file is part of GDB, the GNU debugger.
+
+   Copyright 2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "large-frame.h"
+
+__attribute__ ((noinline)) int
+func (void)
+{
+  int a[4096];
+  blah (a);
+}
diff --git a/gdb/testsuite/gdb.base/large-frame.exp b/gdb/testsuite/gdb.base/large-frame.exp
new file mode 100644
index 00000000000..00090da795e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/large-frame.exp
@@ -0,0 +1,57 @@
+# Copyright 2018 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# This file is part of the gdb testsuite.
+
+# This test was added to test GDB's ability to backtrace over a large
+# stack frame for which there is no debug information.  This should
+# test the non-DWARF stack unwinder.
+#
+# The test was originally added for Risc-V where this case caused a
+# problem at one point, however, there's nothing Risc-V specific in
+# the test.
+
+proc run_test { opt_level } {
+    global srcfile srcfile2 binfile hex
+
+    standard_testfile large-frame-1.c large-frame-2.c
+
+    if {[prepare_for_testing_full "failed to prepare" \
+	     [list ${binfile}-${opt_level} debug \
+		  $srcfile [list debug] \
+		  $srcfile2 [list nodebug optimize=-$opt_level]]]} {
+	return
+    }
+
+    if { ![runto_main] } then {
+	unsupported "runto main"
+	return
+    }
+
+    gdb_breakpoint "blah"
+    gdb_continue_to_breakpoint "blah"
+
+    gdb_test "backtrace" [multi_line \
+			      "#0  blah \[^\n\r\]+" \
+			      "#1  $hex in func \[^\n\r\]+" \
+			      "#2  $hex in main \[^\n\r\]+"]
+}
+
+foreach opt { O0 O1 O2 } {
+    with_test_prefix "optimize=-$opt" {
+	run_test $opt
+    }
+}
+
diff --git a/gdb/testsuite/gdb.base/large-frame.h b/gdb/testsuite/gdb.base/large-frame.h
new file mode 100644
index 00000000000..17058a5efd2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/large-frame.h
@@ -0,0 +1,24 @@
+/* This file is part of GDB, the GNU debugger.
+
+   Copyright 2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef LARGE_FRAME_H
+#define LARGE_FRAME_H
+
+extern void blah (int *);
+extern int func (void);
+
+#endif /* LARGE_FRAME_H */