diff --git a/sparc-dis.c b/sparc-dis.c
index 597dc8a70375355603247326c80c5aaa6f2e2c49..2be874ac94603375f2bcc9aa7042af92ca9dfde0 100644
--- a/sparc-dis.c
+++ b/sparc-dis.c
@@ -2887,7 +2887,9 @@ print_insn_sparc (memaddr, info)
 		    {
 		      const char *name;
 
-		      if (info->mach == bfd_mach_sparc_v9)
+		      if ((info->mach == bfd_mach_sparc_v8plusa) ||
+                          ((info->mach >= bfd_mach_sparc_v9) &&
+                           (info->mach <= bfd_mach_sparc_v9b)))
 			name = sparc_decode_asi_v9 (X_ASI (insn));
 		      else
 			name = sparc_decode_asi_v8 (X_ASI (insn));
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index d0bcd406748b587f104a0998b9fa3b85d41ae476..8cbf0b2e300a72d34d0ade5e4c0770507e00f6fe 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -210,6 +210,7 @@ typedef struct CPUSPARCState {
     uint64_t version;
     uint64_t fprs;
     uint64_t tick_cmpr, stick_cmpr;
+    uint64_t gsr;
 #endif
 #if !defined(TARGET_SPARC64) && !defined(reg_T2)
     target_ulong t2;
diff --git a/target-sparc/op.c b/target-sparc/op.c
index f6d417f4750276cbeb948034579dd09eb3e60323..7ea209ea86f9968eb2fc704217e18f0ffdd0f968 100644
--- a/target-sparc/op.c
+++ b/target-sparc/op.c
@@ -1514,6 +1514,9 @@ void OPPROTO op_saved(void)
     env->cansave++;
     if (env->otherwin == 0)
 	env->canrestore--;
+    else
+	env->otherwin--;
+    FORCE_RET();
 }
 
 void OPPROTO op_restored(void)
@@ -1525,6 +1528,7 @@ void OPPROTO op_restored(void)
 	env->cansave--;
     else
 	env->otherwin--;
+    FORCE_RET();
 }
 
 void OPPROTO op_popc(void)
@@ -1571,3 +1575,23 @@ void OPPROTO op_st_asi()
     helper_st_asi(PARAM1, PARAM2, PARAM3);
 }
 
+#ifdef TARGET_SPARC64
+void OPPROTO op_alignaddr()
+{
+    uint64_t tmp;
+
+    tmp = T0 + T1;
+    env->gsr &= ~7ULL;
+    env->gsr |= tmp & 7ULL;
+    T0 = tmp & ~7ULL;
+}
+
+void OPPROTO op_faligndata()
+{
+    uint64_t tmp;
+
+    tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
+    tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
+    (*((uint64_t *)&DT0)) = tmp;
+}
+#endif
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 26c81454a1b932094ebbf5d7292b289c4beb4596..4a8ad7061bd3c12e143577cab8e0cd610bc68a97 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -364,6 +364,9 @@ GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
 	case 0x80: /* Primary address space */				\
 	    gen_op_##width##_raw();					\
 	    break;							\
+	case 0x82: /* Primary address space, non-faulting load */       \
+	    gen_op_##width##_raw();					\
+	    break;							\
 	default:							\
             break;							\
 	}								\
@@ -1151,6 +1154,12 @@ static void disas_sparc_insn(DisasContext * dc)
 		    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
                     gen_movl_T0_reg(rd);
                     break;
+		case 0x13: /* Graphics Status */
+                    if (gen_trap_ifnofpu(dc))
+                        goto jmp_insn;
+		    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
+                    gen_movl_T0_reg(rd);
+                    break;
 		case 0x17: /* Tick compare */
 		    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
                     gen_movl_T0_reg(rd);
@@ -1166,7 +1175,6 @@ static void disas_sparc_insn(DisasContext * dc)
 		case 0x10: /* Performance Control */
 		case 0x11: /* Performance Instrumentation Counter */
 		case 0x12: /* Dispatch Control */
-		case 0x13: /* Graphics Status */
 		case 0x14: /* Softint set, WO */
 		case 0x15: /* Softint clear, WO */
 		case 0x16: /* Softint write */
@@ -1870,6 +1878,11 @@ static void disas_sparc_insn(DisasContext * dc)
 				    gen_op_sir();
 #endif
 				break;
+			    case 0x13: /* Graphics Status */
+                                if (gen_trap_ifnofpu(dc))
+                                    goto jmp_insn;
+				gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
+				break;
 			    case 0x17: /* Tick compare */
 #if !defined(CONFIG_USER_ONLY)
 				if (!supervisor(dc))
@@ -1895,7 +1908,6 @@ static void disas_sparc_insn(DisasContext * dc)
 			    case 0x10: /* Performance Control */
 			    case 0x11: /* Performance Instrumentation Counter */
 			    case 0x12: /* Dispatch Control */
-			    case 0x13: /* Graphics Status */
 			    case 0x14: /* Softint set */
 			    case 0x15: /* Softint clear */
 			    case 0x16: /* Softint write */
@@ -2077,7 +2089,36 @@ static void disas_sparc_insn(DisasContext * dc)
 			}
 		    case 0x36: /* UltraSparc shutdown, VIS */
 			{
-			    // XXX
+			    int opf = GET_FIELD_SP(insn, 5, 13);
+                            rs1 = GET_FIELD(insn, 13, 17);
+                            rs2 = GET_FIELD(insn, 27, 31);
+
+                            switch (opf) {
+                            case 0x018: /* VIS I alignaddr */
+                                if (gen_trap_ifnofpu(dc))
+                                    goto jmp_insn;
+                                gen_movl_reg_T0(rs1);
+                                gen_movl_reg_T1(rs2);
+                                gen_op_alignaddr();
+                                gen_movl_T0_reg(rd);
+                                break;
+                            case 0x01a: /* VIS I alignaddrl */
+                                if (gen_trap_ifnofpu(dc))
+                                    goto jmp_insn;
+                                // XXX
+                                break;
+                            case 0x048: /* VIS I faligndata */
+                                if (gen_trap_ifnofpu(dc))
+                                    goto jmp_insn;
+                                gen_op_load_fpr_DT0(rs1);
+                                gen_op_load_fpr_DT1(rs2);
+                                gen_op_faligndata();
+                                gen_op_store_DT0_fpr(rd);
+                                break;
+                            default:
+                                goto illegal_insn;
+                            }
+                            break;
 			}
 #endif
 		    default: