diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c
index e4b15b533ba..0c05b79dea4 100644
--- a/sim/riscv/sim-main.c
+++ b/sim/riscv/sim-main.c
@@ -841,6 +841,9 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
 static sim_cia
 execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
 {
+  unsigned_word mask_aq = OP_MASK_AQ << OP_SH_AQ;
+  unsigned_word mask_rl = OP_MASK_RL << OP_SH_RL;
+  unsigned_word mask_aqrl = mask_aq | mask_rl;
   struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
   SIM_DESC sd = CPU_STATE (cpu);
   struct riscv_sim_state *state = RISCV_SIM_STATE (sd);
@@ -853,15 +856,24 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
   struct atomic_mem_reserved_list *amo_prev, *amo_curr;
   unsigned_word tmp;
   sim_cia pc = riscv_cpu->pc + 4;
+  int prev_alignment = current_alignment;
+
+  if (current_alignment != FORCED_ALIGNMENT)
+    current_alignment = STRICT_ALIGNMENT;
 
   /* Handle these two load/store operations specifically.  */
-  switch (op->match)
+  switch (op->match & ~mask_aqrl)
     {
+    case MATCH_LR_D:
     case MATCH_LR_W:
       TRACE_INSN (cpu, "%s %s, (%s);", op->name, rd_name, rs1_name);
-      store_rd (cpu, rd,
-	sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, read_map,
-				   riscv_cpu->regs[rs1]));
+      if (op->xlen_requirement == 64)
+	tmp = sim_core_read_unaligned_8 (cpu, riscv_cpu->pc, read_map,
+					 riscv_cpu->regs[rs1]);
+      else
+	tmp = EXTEND32 (sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, read_map,
+						   riscv_cpu->regs[rs1]));
+      store_rd (cpu, rd, tmp);
 
       /* Walk the reservation list to find an existing match.  */
       amo_curr = state->amo_reserved_list;
@@ -878,6 +890,7 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
       amo_curr->next = state->amo_reserved_list;
       state->amo_reserved_list = amo_curr;
       goto done;
+    case MATCH_SC_D:
     case MATCH_SC_W:
       TRACE_INSN (cpu, "%s %s, %s, (%s);", op->name, rd_name, rs2_name,
 		  rs1_name);
@@ -889,9 +902,14 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
 	  if (amo_curr->addr == riscv_cpu->regs[rs1])
 	    {
 	      /* We found a reservation, so operate it.  */
-	      sim_core_write_unaligned_4 (cpu, riscv_cpu->pc, write_map,
-					  riscv_cpu->regs[rs1],
-					  riscv_cpu->regs[rs2]);
+	      if (op->xlen_requirement == 64)
+		sim_core_write_unaligned_8 (cpu, riscv_cpu->pc, write_map,
+					    riscv_cpu->regs[rs1],
+					    riscv_cpu->regs[rs2]);
+	      else
+		sim_core_write_unaligned_4 (cpu, riscv_cpu->pc, write_map,
+					    riscv_cpu->regs[rs1],
+					    riscv_cpu->regs[rs2]);
 	      store_rd (cpu, rd, 0);
 	      if (amo_curr == state->amo_reserved_list)
 		state->amo_reserved_list = amo_curr->next;
@@ -920,7 +938,7 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
 					       riscv_cpu->regs[rs1]));
   store_rd (cpu, rd, tmp);
 
-  switch (op->match)
+  switch (op->match & ~mask_aqrl)
     {
     case MATCH_AMOADD_D:
     case MATCH_AMOADD_W:
@@ -931,25 +949,37 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
       tmp = riscv_cpu->regs[rd] & riscv_cpu->regs[rs2];
       break;
     case MATCH_AMOMAX_D:
-    case MATCH_AMOMAX_W:
       tmp = max ((signed_word) riscv_cpu->regs[rd],
 		 (signed_word) riscv_cpu->regs[rs2]);
       break;
+    case MATCH_AMOMAX_W:
+      tmp = max ((int32_t) riscv_cpu->regs[rd],
+		 (int32_t) riscv_cpu->regs[rs2]);
+      break;
     case MATCH_AMOMAXU_D:
-    case MATCH_AMOMAXU_W:
       tmp = max ((unsigned_word) riscv_cpu->regs[rd],
 		 (unsigned_word) riscv_cpu->regs[rs2]);
       break;
+    case MATCH_AMOMAXU_W:
+      tmp = max ((uint32_t) riscv_cpu->regs[rd],
+		 (uint32_t) riscv_cpu->regs[rs2]);
+      break;
     case MATCH_AMOMIN_D:
-    case MATCH_AMOMIN_W:
       tmp = min ((signed_word) riscv_cpu->regs[rd],
 		 (signed_word) riscv_cpu->regs[rs2]);
       break;
+    case MATCH_AMOMIN_W:
+      tmp = min ((int32_t) riscv_cpu->regs[rd],
+		 (int32_t) riscv_cpu->regs[rs2]);
+      break;
     case MATCH_AMOMINU_D:
-    case MATCH_AMOMINU_W:
       tmp = min ((unsigned_word) riscv_cpu->regs[rd],
 		 (unsigned_word) riscv_cpu->regs[rs2]);
       break;
+    case MATCH_AMOMINU_W:
+      tmp = min ((uint32_t) riscv_cpu->regs[rd],
+		 (uint32_t) riscv_cpu->regs[rs2]);
+      break;
     case MATCH_AMOOR_D:
     case MATCH_AMOOR_W:
       tmp = riscv_cpu->regs[rd] | riscv_cpu->regs[rs2];
@@ -975,6 +1005,7 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
 				riscv_cpu->regs[rs1], tmp);
 
  done:
+  current_alignment = prev_alignment;
   return pc;
 }
 
@@ -1307,7 +1338,15 @@ execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
   switch (op->insn_class)
     {
     case INSN_CLASS_A:
-      return execute_a (cpu, iw, op);
+      /* Check whether model with A extension is selected.  */
+      if (riscv_cpu->csr.misa & 1)
+	return execute_a (cpu, iw, op);
+      else
+	{
+	  TRACE_INSN (cpu, "UNHANDLED EXTENSION: %d", op->insn_class);
+	  sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled,
+			   SIM_SIGILL);
+	}
     case INSN_CLASS_C:
       /* Check whether model with C extension is selected.  */
       if (riscv_cpu->csr.misa & 4)
