diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index a83b456..fe5b6f8 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -644,7 +644,9 @@ TARGET_OBS = @TARGET_OBS@
 # All target-dependent objects files that require 64-bit CORE_ADDR
 # (used with --enable-targets=all --enable-64-bit-bfd).
 ALL_64_TARGET_OBS = \
-	aarch64-tdep.o aarch64-linux-tdep.o aarch64-newlib-tdep.o aarch64-insn.o \
+	aarch64-tdep.o aarch64-linux-tdep.o aarch64-newlib-tdep.o \
+	aarch64-insn.o \
+	arm-insn-utils.o \
 	alphabsd-tdep.o alphafbsd-tdep.o alpha-linux-tdep.o alpha-mdebug-tdep.o \
 	alphanbsd-tdep.o alphaobsd-tdep.o alpha-tdep.o \
 	amd64fbsd-tdep.o amd64-darwin-tdep.o amd64-dicos-tdep.o \
@@ -662,8 +664,9 @@ ALL_TARGET_OBS = \
 	arm-linux.o \
 	arm-linux-tdep.o \
 	arm-get-next-pcs.o \
-	arm-symbian-tdep.o \
+	arm-insn-emit.o \
 	arm-insn-reloc.o \
+	arm-symbian-tdep.o \
 	armnbsd-tdep.o armobsd-tdep.o \
 	arm-tdep.o arm-wince-tdep.o \
 	avr-tdep.o \
@@ -994,7 +997,8 @@ common/common-exceptions.h target/target.h common/symbol.h \
 common/common-regcache.h fbsd-tdep.h nat/linux-personality.h \
 common/fileio.h nat/x86-linux.h nat/x86-linux-dregs.h nat/amd64-linux-siginfo.h\
 nat/linux-namespaces.h arch/arm.h common/gdb_sys_time.h arch/aarch64-insn.h \
-tid-parse.h ser-event.h arch/arm-insn-reloc.h
+tid-parse.h ser-event.h arch/arm-insn-emit.h arch/arm-insn-reloc.h \
+arch/arm-insn-utils.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -2315,6 +2319,10 @@ arm-linux.o: ${srcdir}/arch/arm-linux.c
 	$(COMPILE) $(srcdir)/arch/arm-linux.c
 	$(POSTCOMPILE)
 
+arm-insn-emit.o: ${srcdir}/arch/arm-insn-emit.c
+	$(COMPILE) $(srcdir)/arch/arm-insn-emit.c
+	$(POSTCOMPILE)
+
 arm-insn-reloc.o: ${srcdir}/arch/arm-insn-reloc.c
 	$(COMPILE) $(srcdir)/arch/arm-insn-reloc.c
 	$(POSTCOMPILE)
@@ -2397,6 +2405,10 @@ aarch64-insn.o: ${srcdir}/arch/aarch64-insn.c
 	$(COMPILE) $(srcdir)/arch/aarch64-insn.c
 	$(POSTCOMPILE)
 
+arm-insn-utils.o: ${srcdir}/arch/arm-insn-utils.c
+	$(COMPILE) $(srcdir)/arch/arm-insn-utils.c
+	$(POSTCOMPILE)
+
 #
 # gdb/tui/ dependencies
 #
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index e5ce13e..67c10f2 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -57,6 +57,7 @@
 
 #include "features/aarch64.c"
 
+#include "arch/arm-insn-utils.h"
 #include "arch/aarch64-insn.h"
 
 #include "opcode/aarch64.h"
@@ -2471,7 +2472,7 @@ aarch64_displaced_step_ldr_literal (const int32_t offset, const int is_sw,
   struct aarch64_displaced_step_data *dsd
     = (struct aarch64_displaced_step_data *) data;
   CORE_ADDR address = data->insn_addr + offset;
-  struct aarch64_memory_operand zero = { MEMORY_OPERAND_OFFSET, 0 };
+  struct arm_memory_operand zero = { MEMORY_OPERAND_OFFSET, 0 };
 
   regcache_cooked_write_unsigned (dsd->regs, AARCH64_X0_REGNUM + rt,
 				  address);
diff --git a/gdb/arch/aarch64-insn.c b/gdb/arch/aarch64-insn.c
index 772512b..88fbffe 100644
--- a/gdb/arch/aarch64-insn.c
+++ b/gdb/arch/aarch64-insn.c
@@ -17,6 +17,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "common-defs.h"
+#include "arm-insn-utils.h"
 #include "aarch64-insn.h"
 
 /* Toggle this file's internal debugging dump.  */
@@ -346,7 +347,7 @@ aarch64_emit_load_store (uint32_t *buf, uint32_t size,
 			 enum aarch64_opcodes opcode,
 			 struct aarch64_register rt,
 			 struct aarch64_register rn,
-			 struct aarch64_memory_operand operand)
+			 struct arm_memory_operand operand)
 {
   uint32_t op;
 
diff --git a/gdb/arch/aarch64-insn.h b/gdb/arch/aarch64-insn.h
index a799515..511a80c 100644
--- a/gdb/arch/aarch64-insn.h
+++ b/gdb/arch/aarch64-insn.h
@@ -117,36 +117,6 @@ struct aarch64_register
   int is64;
 };
 
-enum aarch64_memory_operand_type
-{
-  MEMORY_OPERAND_OFFSET,
-  MEMORY_OPERAND_PREINDEX,
-  MEMORY_OPERAND_POSTINDEX,
-};
-
-/* Representation of a memory operand, used for load and store
-   instructions.
-
-   The types correspond to the following variants:
-
-   MEMORY_OPERAND_OFFSET:    LDR rt, [rn, #offset]
-   MEMORY_OPERAND_PREINDEX:  LDR rt, [rn, #index]!
-   MEMORY_OPERAND_POSTINDEX: LDR rt, [rn], #index  */
-
-struct aarch64_memory_operand
-{
-  /* Type of the operand.  */
-  enum aarch64_memory_operand_type type;
-
-  /* Index from the base register.  */
-  int32_t index;
-};
-
-/* Helper macro to mask and shift a value into a bitfield.  */
-
-#define ENCODE(val, size, offset) \
-  ((uint32_t) ((val & ((1ULL << size) - 1)) << offset))
-
 int aarch64_decode_adr (CORE_ADDR addr, uint32_t insn, int *is_adrp,
 			unsigned *rd, int32_t *offset);
 
@@ -319,6 +289,6 @@ int aarch64_emit_load_store (uint32_t *buf, uint32_t size,
 			     enum aarch64_opcodes opcode,
 			     struct aarch64_register rt,
 			     struct aarch64_register rn,
-			     struct aarch64_memory_operand operand);
+			     struct arm_memory_operand operand);
 
 #endif
diff --git a/gdb/arch/arm-insn-emit.c b/gdb/arch/arm-insn-emit.c
new file mode 100644
index 0000000..810172d
--- /dev/null
+++ b/gdb/arch/arm-insn-emit.c
@@ -0,0 +1,1550 @@
+/* Copyright (C) 2015-2016 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 "common-defs.h"
+#include "arm.h"
+#include "arm-insn-utils.h"
+#include "arm-insn-emit.h"
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
+/* Encode a bitfield with a repetition of BIT starting at from FROM for
+   LENGHT.  Max 16 bits.  */
+
+static uint16_t
+repeat_bit (uint8_t bit, uint8_t from, uint8_t length)
+{
+  uint16_t value = 0;
+  int i;
+
+  for (i = from; i - from < length; i++)
+    {
+      value |= ENCODE (bit & 1, 1, i);
+    }
+
+  return value;
+}
+
+/* See arm-insn-emit.h.  */
+
+uint16_t
+encode_register_list (uint8_t from, uint8_t length, uint16_t initial)
+{
+  return repeat_bit (1, from, length) | initial;
+}
+
+/* See arm-insn-emit.h.  */
+
+struct arm_operand
+immediate_operand (uint32_t imm)
+{
+  struct arm_operand operand;
+
+  operand.type = OPERAND_IMMEDIATE;
+  operand.imm = imm;
+
+  return operand;
+}
+
+/* Helper function to create a register operand, for instructions with
+   different types of operands.
+
+   For example:
+   p += emit_mov (p, x0, register_operand (x1));  */
+
+/* See arm-insn-emit.h.  */
+
+struct arm_operand
+register_operand (uint8_t reg)
+{
+  struct arm_operand operand;
+
+  operand.type = OPERAND_REGISTER;
+  operand.reg = reg;
+
+  return operand;
+}
+
+/* See arm-insn-emit.h.  */
+
+struct arm_operand
+memory_operand (struct arm_memory_operand mem)
+{
+  struct arm_operand operand;
+
+  operand.type = OPERAND_MEMORY;
+  operand.mem = mem;
+
+  return operand;
+}
+
+/* Write a 32-bit unsigned integer INSN info *BUF.  Return the number of
+   instructions written (aka. 1).  */
+
+static int
+arm_emit_arm_insn (uint32_t *buf, uint32_t insn)
+{
+  *buf = insn;
+  return 1;
+}
+
+/* Write a 16-bit unsigned integer INSN info *BUF.  Return the number of
+   instructions written (aka. 1).  */
+
+static int
+arm_emit_thumb_insn (uint16_t *buf, uint16_t insn)
+{
+  *buf = insn;
+  return 1;
+}
+
+/* Write a 32-bit unsigned integer INSN representing a Thumb-2 wide
+   instruction info *BUF.  Return the number of instructions written
+   (aka. 2).  */
+
+static int
+arm_emit_thumb_w_insn (uint16_t *buf, uint32_t insn)
+{
+  int res = arm_emit_thumb_insn (buf, bits (insn, 16, 31));
+  res += arm_emit_thumb_insn (buf + res, bits (insn, 0, 15));
+  return res;
+}
+
+/* See arm-insn-emit.h.  */
+
+uint32_t
+arm_arm_branch_relative_distance (CORE_ADDR from, CORE_ADDR to)
+{
+  return arm_arm_branch_adjusted_offset ((uint32_t) to - (uint32_t) from);
+}
+
+/* See arm-insn-emit.h.  */
+
+uint32_t
+arm_thumb_branch_relative_distance (CORE_ADDR from, CORE_ADDR to)
+{
+  uint32_t from_ = ((uint32_t) from) & ~1;
+  uint32_t to_ = ((uint32_t) to) & ~1;
+  return arm_thumb_branch_adjusted_offset (to_ - from_);
+}
+
+/* See arm-insn-emit.h.  */
+
+uint32_t
+arm_thumb_to_arm_branch_relative_distance (CORE_ADDR from, CORE_ADDR to)
+{
+  uint32_t from_ = ((uint32_t) from) & ~3;
+  uint32_t to_ = ((uint32_t) to) & ~3;
+  return arm_thumb_branch_adjusted_offset (to_ - from_);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_arm_is_reachable (CORE_ADDR from, CORE_ADDR to)
+{
+  int32_t rel = arm_arm_branch_relative_distance (from, to);
+  rel >>= 25;
+  return !rel || !(rel + 1);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_thumb_is_reachable (CORE_ADDR from, CORE_ADDR to)
+{
+  int32_t rel = arm_thumb_branch_relative_distance (from, to);
+  rel >>= 24;
+  return !rel || !(rel + 1);
+}
+
+/* See arm-insn-emit.h.  */
+
+uint32_t
+arm_arm_branch_adjusted_offset (uint32_t offset)
+{
+  return offset - 8;
+}
+
+/* See arm-insn-emit.h.  */
+
+uint32_t
+arm_thumb_branch_adjusted_offset (uint32_t offset)
+{
+  return offset - 4;
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_mov_32 (uint16_t *mem, int reg, uint32_t val)
+{
+  uint16_t val_low = bits (val, 0, 15);
+  uint16_t val_high = bits (val, 16, 31);
+  int res = 0;
+
+  res += arm_emit_thumb_movw (mem, reg, immediate_operand (val_low));
+  res += arm_emit_thumb_movt (mem + res, reg, immediate_operand (val_high));
+
+  return res;
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_mov_32 (uint32_t *mem, int reg, uint32_t val)
+{
+  uint16_t val_low = bits (val, 0, 15);
+  uint16_t val_high = bits (val, 16, 31);
+  int res = 0;
+
+  res += arm_emit_arm_movw (mem, INST_AL, reg, immediate_operand (val_low));
+  res += arm_emit_arm_movt (mem + res, INST_AL, reg,
+			    immediate_operand (val_high));
+
+  return res;
+}
+
+/* Write ARM branch instructions into *BUF.
+
+   This is a base function to write
+   B, BL and BLX instructions with immediate or register operands.
+
+   Proper encodings documentation is provided in the
+   arm_emit_arm_{b_,bl_,blx} helper functions.
+
+   L if set a bl instruction will be written.
+   X if set a blx instruction will be written.  */
+
+static int
+arm_emit_arm_branch (uint32_t *buf, uint8_t cond,
+		     struct arm_operand operand,
+		     uint8_t l, uint8_t x)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      /* BLX  */
+      if (l == 1 && x == 1)
+	{
+	  cond = 0xF;
+	  l = bit (operand.imm, 1);
+	}
+      /* Encode B, BL or BLX.  */
+      return arm_emit_arm_insn (buf, (ARM_B
+				      | ENCODE (l, 1, 24)
+				      | ENCODE (cond, 4, 28)
+				      | ENCODE (operand.imm >> 2, 24, 0)));
+    }
+  else if (operand.type == OPERAND_REGISTER)
+    {
+      if (l == 1 && x == 1)
+	{
+	  return arm_emit_arm_insn (buf, (ARM_BLX
+					  | ENCODE (cond, 4, 28)
+					  | ENCODE (operand.reg, 4, 0)));
+	}
+      else
+	{
+	  /* error. Only BLX has a register operand.  */
+	  throw_error (NOT_SUPPORTED_ERROR,
+		       _("Unimplemented instruction encoding."));
+	}
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* Write Thumb branch instructions into *BUF.
+
+   This is a base function to write
+   BW, BL and BLX instructions with immediate or register operand.
+
+   Proper encodings documentation is provided in the
+   arm_emit_thumb_{bw_,bl_,blx} helper functions.
+
+   REL is the relative offset of the label.
+   L if set a bl instruction will be written.
+   X if set a blx instruction will be written.  */
+
+int
+arm_emit_thumb_branch (uint16_t *buf, struct arm_operand operand,
+		       uint8_t l, uint8_t x)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      uint32_t imm10, imm11;
+      uint32_t s, j1, j2;
+
+      if (x == 0)
+	imm11 = bits (operand.imm, 1, 11);
+      else
+	/* IMM10L:H.  */
+	imm11 = bits (operand.imm, 2, 11) << 1;
+
+      imm10 = bits (operand.imm, 12, 21);
+      s = bit (operand.imm, 24);
+      j1 = s ^ !(bit (operand.imm, 23));
+      j2 = s ^ !(bit (operand.imm, 22));
+
+      return arm_emit_thumb_w_insn (buf, (THUMB_BW
+					  | ENCODE (s, 1, 26)
+					  | ENCODE (imm10, 10, 16)
+					  | ENCODE (l, 1, 14)
+					  | ENCODE (j1, 1, 13)
+					  | ENCODE (x == 0 ? 1 : 0, 1, 12)
+					  | ENCODE (j2, 1, 11)
+					  | ENCODE (imm11, 11, 0)));
+    }
+  else if (operand.type == OPERAND_REGISTER)
+    {
+      if (l == 1 && x == 1)
+        return arm_emit_thumb_insn (buf, (THUMB_BLX
+					  | ENCODE (operand.reg, 4, 3)));
+      else
+	{
+	  throw_error (NOT_SUPPORTED_ERROR,
+		       _("Unimplemented instruction encoding."));
+	}
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_b (uint32_t *buf, uint8_t cond, uint32_t rel)
+{
+  return arm_emit_arm_branch (buf, cond, immediate_operand (rel), 0, 0);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_bl (uint32_t *buf, uint8_t cond, uint32_t rel)
+{
+  return arm_emit_arm_branch (buf, cond, immediate_operand (rel), 1, 0);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_bl (uint16_t *buf, uint32_t rel)
+{
+  return arm_emit_thumb_branch (buf, immediate_operand (rel), 1, 0);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_b (uint16_t *buf, uint8_t cond, uint32_t rel)
+{
+  return arm_emit_thumb_insn (buf, (THUMB_B
+				    | ENCODE (cond, 4, 8)
+				    | ENCODE (rel >> 1, 8, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_bw (uint16_t *buf, uint32_t rel)
+{
+  return arm_emit_thumb_branch (buf, immediate_operand (rel), 0, 0);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_bw_cond (uint16_t *buf, uint8_t cond, uint32_t rel)
+{
+  uint32_t imm6, imm11;
+  uint32_t s, j1, j2;
+
+  imm11 = bits (rel, 1, 11);
+  imm6 = bits (rel, 12, 17);
+  s = bit (rel, 24);
+  j1 = s ^ !(bit (rel, 23));
+  j2 = s ^ !(bit (rel, 22));
+
+  return arm_emit_thumb_w_insn (buf, (THUMB_BW
+				      | ENCODE (s, 1, 26)
+				      | ENCODE (imm6, 6, 16)
+				      | ENCODE (cond, 4, 22)
+				      | ENCODE (j1, 1, 13)
+				      | ENCODE (j2, 1, 11)
+				      | ENCODE (imm11, 11, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_blx (uint16_t *buf, struct arm_operand operand)
+{
+  return arm_emit_thumb_branch (buf, operand, 1, 1);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_blx (uint32_t *buf, uint8_t cond, struct arm_operand operand)
+{
+  return arm_emit_arm_branch (buf, cond, operand, 1, 1);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_movw (uint32_t *buf, uint8_t cond, uint8_t rd,
+		   struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_insn (buf,
+				(ARM_MOVW
+				 | ENCODE (cond, 4, 28)
+				 | ENCODE (bits (operand.imm, 12, 15), 4, 16)
+				 | ENCODE (rd, 4, 12)
+				 | ENCODE (bits (operand.imm, 0, 11), 12, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_mov (uint32_t *buf, uint8_t cond, uint8_t rd,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_insn (buf,
+				(ARM_MOV
+				 | ENCODE (cond, 4, 28)
+				 /* Immediate value opcode.  */
+				 | ENCODE (1, 1, 25)
+				 | ENCODE (rd, 4, 12)
+				 | ENCODE (bits (operand.imm, 0, 11), 12, 0)));
+    }
+  else if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_insn (buf, (ARM_MOV
+				      | ENCODE (cond, 4, 28)
+				      | ENCODE (rd, 4, 12)
+				      | ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_movw (uint16_t *buf, uint8_t rd, struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_w_insn (buf,
+				    (THUMB_MOVW
+				     | ENCODE (bit (operand.imm, 11), 1, 26)
+				     | ENCODE (bits (operand.imm, 12, 15),
+					       4, 16)
+				     | ENCODE (bits (operand.imm, 8, 10), 3, 12)
+				     | ENCODE (rd, 4, 8)
+				     | ENCODE (bits (operand.imm, 0, 7),
+					       8, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_movt (uint32_t *buf, uint8_t cond, uint8_t rd,
+		   struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_insn (buf,
+				(ARM_MOVT
+				 | ENCODE (cond, 4, 28)
+				 | ENCODE (bits (operand.imm, 12, 15), 4, 16)
+				 | ENCODE (rd, 4, 12)
+				 | ENCODE (bits (operand.imm, 0, 11), 12, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_movt (uint16_t *buf, uint8_t rd, struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_w_insn (buf,
+				    (THUMB_MOVT
+				     | ENCODE (bit (operand.imm, 11), 1, 26)
+				     | ENCODE (bits (operand.imm, 12, 15),
+					       4, 16)
+				     | ENCODE (bits (operand.imm, 8, 10), 3, 12)
+				     | ENCODE (rd, 4, 8)
+				     | ENCODE (bits (operand.imm, 0, 7),8, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_vpush (uint32_t *buf, uint8_t cond, uint8_t rs, uint8_t len)
+{
+  return arm_emit_arm_insn (buf, (ARM_VPUSH
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (bit (rs, 4), 1, 22)
+				  | ENCODE (bits (rs, 0, 3), 4, 12)
+				  | ENCODE (2 * len, 8, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_vpush (uint16_t *buf, uint8_t rs, uint8_t len)
+{
+  return arm_emit_thumb_w_insn (buf, (THUMB_VPUSH
+				      | ENCODE (bit (rs, 4), 1, 22)
+				      | ENCODE (bits (rs, 0, 3), 4, 12)
+				      | ENCODE (2 * len, 8, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_push_list (uint32_t *buf, uint8_t cond, uint16_t register_list)
+{
+  return arm_emit_arm_insn (buf, (ARM_PUSH_A1
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (register_list, 16, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_push_one (uint32_t *buf, uint8_t cond, uint8_t rt)
+{
+  return arm_emit_arm_insn (buf, (ARM_PUSH_A2
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (rt, 4, 12)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_push_one (uint16_t *buf, uint8_t register_list, uint8_t lr)
+{
+  return arm_emit_thumb_insn (buf, (THUMB_PUSH_T1
+				    | ENCODE (register_list, 8, 0)
+				    | ENCODE (lr, 1, 8)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_push_list (uint16_t *buf,
+			  uint16_t register_list,
+			  uint8_t lr)
+{
+  return arm_emit_thumb_w_insn (buf, (THUMB_PUSH_T2
+				      | ENCODE (bit (lr, 0), 1, 14)
+				      | ENCODE (register_list, 13, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_mrs (uint32_t *buf,
+		  uint8_t cond,
+		  uint8_t rd)
+{
+  return arm_emit_arm_insn (buf, (ARM_MRS
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (rd, 4, 12)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_mrs (uint16_t *buf, uint8_t rd)
+{
+  return arm_emit_thumb_w_insn (buf, THUMB_MRS | ENCODE (rd, 4, 12));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_mov (uint16_t *buf, uint8_t rd, struct arm_operand operand)
+{
+   if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_thumb_insn (buf, (THUMB_MOV
+					| ENCODE (bit (rd, 3), 1, 7)
+					| ENCODE (bits (rd, 0, 2), 3, 0)
+					| ENCODE (operand.reg, 4, 3)));
+    }
+   else
+     {
+       throw_error (NOT_SUPPORTED_ERROR,
+		    _("Unimplemented instruction encoding."));
+     }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_dmb (uint32_t *buf)
+{
+  return arm_emit_arm_insn (buf, ARM_DMB | ENCODE (0xF, 4, 0));
+
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_dmb (uint16_t *buf)
+{
+  return arm_emit_thumb_w_insn (buf, THUMB_DMB | ENCODE (0xF, 4, 0));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_ldrex (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn)
+{
+  return arm_emit_arm_insn (buf, (ARM_LDREX
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (rn, 4, 16)
+				  | ENCODE (rt, 4, 12)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_ldrex (uint16_t *buf, int8_t rt, uint8_t rn,
+			  struct arm_operand operand)
+{
+
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_w_insn (buf,
+				    (THUMB_LDREX
+				     | ENCODE (rn, 4, 16)
+				     | ENCODE (rt, 4, 12)
+				     | ENCODE (bits (operand.imm, 0, 7),
+					       8, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_cmp (uint32_t *buf, uint8_t cond, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_insn (buf,
+				(ARM_CMP
+				 | ENCODE (cond, 4, 28)
+				 /* Immediate.  */
+				 | ENCODE (1, 1, 25)
+				 | ENCODE (rn, 4, 16)
+				 | ENCODE (bits (operand.imm, 0, 11), 12, 0)));
+    }
+  else if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_insn (buf, (ARM_CMP
+				      | ENCODE (cond, 4, 28)
+				      | ENCODE (rn, 4, 16)
+				      | ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_cmp (uint16_t *buf, uint8_t rn, struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_insn (buf,
+				  (THUMB_CMP
+				   | ENCODE (rn, 3, 8)
+				   | ENCODE (bits (operand.imm, 0, 7), 8, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_cmpw (uint16_t *buf, uint8_t rn, struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_w_insn (buf,
+				    (THUMB_CMPW
+				     | ENCODE (rn, 4, 16)
+				     | ENCODE (bit (operand.imm, 11), 1, 26)
+				     | ENCODE (bits (operand.imm, 8, 10), 3, 12)
+				     | ENCODE (bits (operand.imm, 0, 7),
+					       8, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_bic (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_insn (buf,
+				(ARM_BIC
+				 | ENCODE (cond, 4, 28)
+				 | ENCODE (rn, 4, 16)
+				 | ENCODE (rd, 4, 12)
+				 | ENCODE (bits (operand.imm, 0, 11), 12, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_bic (uint16_t *buf, uint8_t rd, uint8_t rn,
+		    struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_w_insn (buf,
+				    (THUMB_BIC
+				     | ENCODE (bit (operand.imm, 11), 1, 26)
+				     | ENCODE (rn, 4, 16)
+				     | ENCODE (rd, 4, 8)
+				     | ENCODE (bits (operand.imm, 8, 10), 3, 12)
+				     | ENCODE (bits (operand.imm, 0, 7),
+					       8, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_strex (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rt,
+		    uint8_t rn)
+{
+  return arm_emit_arm_insn (buf, (ARM_STREX
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (rn, 4, 16)
+				  | ENCODE (rd, 4, 12)
+				  | ENCODE (rt, 4, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_strex (uint16_t *buf, uint8_t rd, uint8_t rt, uint8_t rn,
+		      struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_w_insn (buf, (THUMB_STREX
+					  | ENCODE (rn, 4, 16)
+					  | ENCODE (rt, 4, 12)
+					  | ENCODE (rd, 4, 8)
+					  | ENCODE (operand.imm, 8, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_str (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_MEMORY)
+    {
+      switch (operand.mem.type)
+	{
+	case MEMORY_OPERAND_OFFSET:
+	  {
+	    return arm_emit_arm_insn (buf,
+				      (ARM_STR
+				       | ENCODE (cond, 4, 28)
+				       /* P.  */
+				       | ENCODE (1, 1, 24)
+				       /* U.  */
+				       | ENCODE (operand.mem.index < 0 ? 0 : 1,
+						 1, 23)
+				       | ENCODE (rn, 4, 16)
+				       | ENCODE (rt, 4, 12)
+				       | ENCODE (bits (ABS (operand.mem.index),
+						       0, 11), 12, 0)));
+
+	  }
+	default:
+	  {
+	    throw_error (NOT_SUPPORTED_ERROR,
+			 _("Unimplemented instruction encoding."));
+	  }
+	}
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_str (uint16_t *buf, uint8_t rt, uint8_t rn,
+		    struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_insn (buf, (THUMB_STR
+					| ENCODE (operand.imm, 5, 6)
+					| ENCODE (rn, 3, 3)
+					| ENCODE (rt, 3, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+
+}
+
+/* Helper function to emit data processing register instructions.  */
+
+static int
+arm_emit_arm_data_processing_reg (uint32_t *buf, uint32_t opcode,
+				  uint8_t cond, uint8_t flags,
+				  uint32_t operands)
+{
+  return arm_emit_arm_insn (buf, (opcode
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (flags, 1, 20)
+				  /* No shift.  */
+				  | ENCODE (0, 5, 7)
+				  | ENCODE (0, 2, 5)
+				  | operands));
+}
+
+/* Helper function to emit data processing immediate instructions.  */
+
+static int
+arm_emit_arm_data_processing_imm (uint32_t *buf, uint32_t opcode, uint8_t cond,
+				  uint8_t rn, uint32_t operands)
+{
+  return arm_emit_arm_insn (buf, (opcode
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (rn, 4, 16)
+				  | operands));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_add (uint32_t *buf, uint8_t cond, uint8_t flags, uint8_t rd,
+		  uint8_t rn, struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_insn (buf, (ARM_ADD
+				      /* Immediate operand */
+				      | ENCODE (1, 1, 25)
+				      | ENCODE (cond, 4, 28)
+				      | ENCODE (flags, 1, 20)
+				      | ENCODE (rn, 4, 16)
+				      | ENCODE (rd, 4, 12)
+				      | ENCODE (operand.imm, 8, 0)));
+    }
+  else if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_ADD, cond, flags,
+					       (ENCODE (rn, 4, 16)
+						| ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_adc (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+  else if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_ADC, cond, 0,
+					       (ENCODE (rn, 4, 16)
+						| ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_add_sp (uint16_t *buf, struct arm_operand operand)
+{
+  if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_thumb_insn (buf, (THUMB_ADD_SP
+					| ENCODE (operand.imm >> 2, 7, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_pop_one (uint32_t *buf, uint8_t cond, uint8_t rt)
+{
+  return arm_emit_arm_insn (buf, (ARM_POP_A2
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (rt, 4, 12)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_pop_list (uint32_t *buf, uint8_t cond, uint16_t register_list)
+{
+  return arm_emit_arm_insn (buf, (ARM_POP_A1
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (register_list, 16, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_pop (uint16_t *buf, uint8_t register_list, uint8_t pc)
+{
+  return arm_emit_thumb_insn (buf, (THUMB_POP
+				    | ENCODE (pc, 1, 8)
+				    | ENCODE (register_list, 8, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_popw_list (uint16_t *buf, uint16_t register_list, uint8_t pc,
+			  uint8_t lr)
+{
+  return arm_emit_thumb_w_insn (buf, (THUMB_POPW
+				      | ENCODE (pc, 1, 15)
+				      | ENCODE (lr, 1, 14)
+				      | ENCODE (register_list, 13, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_msr (uint32_t *buf, uint8_t cond, uint8_t rn)
+{
+  return arm_emit_arm_insn (buf, (ARM_MSR
+				  | ENCODE (cond, 4, 28)
+				  /* Mask 0b11  */
+				  | ENCODE (3, 2, 18)
+				  | ENCODE (rn, 4, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_msr (uint16_t *buf, uint8_t rn)
+{
+  return arm_emit_thumb_w_insn (buf, (THUMB_MSR
+				      | ENCODE (rn, 4, 16)
+				      /* Mask 0b11  */
+				      | ENCODE (3, 2, 10)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_vpop (uint32_t *buf, uint8_t cond, uint8_t rs, uint8_t len)
+{
+  return arm_emit_arm_insn (buf, (ARM_VPOP
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (bit (rs, 4), 1, 22)
+				  | ENCODE (bits (rs, 0, 3), 4, 12)
+				  | ENCODE (2 * len, 8, 0)));
+
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_thumb_vpop (uint16_t *buf, uint8_t rs, uint8_t len)
+{
+  return arm_emit_thumb_w_insn (buf, (THUMB_VPOP
+				      | ENCODE (bit (rs, 4), 1, 22)
+				      | ENCODE (bits (rs, 0, 3), 4, 12)
+				      | ENCODE (2 * len, 8, 0)));
+}
+
+/* Helper function for LDR and LDRB instructions.  */
+
+static int
+arm_emit_arm_ldr_ldrb (uint32_t *buf, uint32_t opcode, uint8_t cond, uint8_t rt,
+		       uint8_t rn, struct arm_memory_operand operand)
+{
+  switch (operand.type)
+    {
+    case MEMORY_OPERAND_OFFSET:
+      {
+	/* Offset P 1 , W 0 */
+	/* Pre indexed P 1 W 1 */
+	/* Post indexed P 0 W1 */
+	/* U 1 if offset add */
+	/* U 0 if offset sub */
+
+	/* Offset P1 , W0.  */
+	uint32_t offset_op = ENCODE (1, 1, 24) | ENCODE (0, 1, 21);
+
+	/* U1 if offset added or omitted, U0 if subtracted.  */
+	if (operand.index >= 0)
+	  offset_op |= ENCODE (1, 1, 23);
+
+	return arm_emit_arm_insn (buf, (opcode
+					| ENCODE (cond, 4, 28)
+					| offset_op
+					| ENCODE (rn, 4, 16)
+					| ENCODE (rt, 4, 12)
+					| ENCODE (ABS (operand.index), 12, 0)));
+      }
+    default:
+      {
+	throw_error (NOT_SUPPORTED_ERROR,
+		     _("Unimplemented instruction encoding."));
+      }
+    }
+}
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_ldr (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		  struct arm_memory_operand operand)
+{
+  return arm_emit_arm_ldr_ldrb (buf, ARM_LDR, cond, rt, rn, operand);
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_ldrb (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		   struct arm_memory_operand operand)
+{
+  return arm_emit_arm_ldr_ldrb (buf, ARM_LDRB, cond, rt, rn, operand);
+}
+
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_ldrh (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		   struct arm_memory_operand operand)
+{
+  switch (operand.type)
+    {
+    case MEMORY_OPERAND_OFFSET:
+      {
+	/* Offset P 1 , W 0 */
+	/* Pre indexed P 1 W 1 */
+	/* Post indexed P 0 W1 */
+	/* U 1 if offset add */
+	/* U 0 if offset sub */
+
+	/* Offset P1 , W0.  */
+	uint32_t offset_op = ENCODE (1, 1, 24) | ENCODE (0, 1, 21);
+
+	/* U1 if offset added or omitted, U0 if subtracted.  */
+	if (operand.index >= 0)
+	  offset_op |= ENCODE (1, 1, 23);
+
+	return arm_emit_arm_insn (buf,
+				  (ARM_LDRH
+				   | ENCODE (cond, 4, 28)
+				   | offset_op
+				   | ENCODE (rn, 4, 16)
+				   | ENCODE (rt, 4, 12)
+				   | ENCODE (bits(ABS (operand.index), 4, 7),
+					     4, 8)
+				   | ENCODE (bits(ABS (operand.index), 0, 3),
+					     4, 0)));
+      }
+    default:
+      {
+	throw_error (NOT_SUPPORTED_ERROR,
+		     _("Unimplemented instruction encoding."));
+      }
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_ldrd (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		   struct arm_memory_operand operand)
+{
+  switch (operand.type)
+    {
+    case MEMORY_OPERAND_OFFSET:
+      {
+	/* Offset P 1 , W 0 */
+	/* Pre indexed P 1 W 1 */
+	/* Post indexed P 0 W1 */
+	/* U 1 if offset add */
+	/* U 0 if offset sub */
+
+	/* Offset P1 , W0.  */
+	uint32_t offset_op = ENCODE (1, 1, 24) | ENCODE (0, 1, 21);
+
+	/* U1 if offset added or omitted, U0 if subtracted.  */
+	if (operand.index >= 0)
+	  offset_op |= ENCODE (1, 1, 23);
+
+	return arm_emit_arm_insn (buf,
+				  (ARM_LDRD
+				   | ENCODE (cond, 4, 28)
+				   | offset_op
+				   | ENCODE (rn, 4, 16)
+				   | ENCODE (rt, 4, 12)
+				   | ENCODE (bits(ABS (operand.index), 4, 7),
+					     4, 8)
+				   | ENCODE (bits(ABS (operand.index), 0, 3),
+					     4, 0)));
+      }
+    default:
+      {
+	throw_error (NOT_SUPPORTED_ERROR,
+		     _("Unimplemented instruction encoding."));
+      }
+    }
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_sbfx (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		   uint32_t lsb, uint32_t width)
+{
+  return arm_emit_arm_insn (buf, (ARM_SBFX
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE ((width - 1), 5, 16)
+				  | ENCODE (rd, 4, 12)
+				  | ENCODE (lsb, 5, 7)
+				  | ENCODE (rn, 4, 0)));
+}
+
+/* See arm-insn-emit.h.  */
+
+int
+arm_emit_arm_nop (uint32_t *buf, uint8_t cond)
+{
+  return arm_emit_arm_insn (buf, ARM_NOP | ENCODE (cond, 4, 28));
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_ubfx (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		   uint8_t lsb, uint8_t width)
+{
+  return arm_emit_arm_insn (buf, (ARM_UBFX
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE ((lsb + width - 1), 5, 16)
+				  | ENCODE (rd, 4, 12)
+				  | ENCODE (lsb, 5, 7)
+				  | ENCODE (rn, 4, 0)));
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_sub (uint32_t *buf, uint8_t cond, uint8_t flags,
+		  uint8_t rd, uint8_t rn, struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_SUB, cond, flags,
+					       (ENCODE (rn, 4, 16)
+						| ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_data_processing_imm (buf,
+					       (ARM_SUB
+						/* Immediate.  */
+						| ENCODE (1, 1, 25)
+						| ENCODE (flags, 1, 20)),
+					       cond, rn,
+					       (ENCODE (rd, 4, 12)
+						| ENCODE (operand.imm, 12, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_rsb (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_RSB, cond, 0,
+					       (ENCODE (rn, 4, 16)
+						| ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_data_processing_imm (buf,
+					       (ARM_RSB
+						/* Immediate.  */
+						| ENCODE (1, 1, 25)
+						| ENCODE (0, 1, 20)),
+					       cond, rn,
+					       (ENCODE (rd, 4, 12)
+						| ENCODE (operand.imm, 12, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_sbc (uint32_t *buf, uint8_t cond, uint8_t flags, uint8_t rd,
+		  uint8_t rn, struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_SBC, cond, flags,
+					       (ENCODE (rn, 4, 16)
+						| ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int arm_emit_arm_mul (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_MUL, cond, 0,
+					       (ENCODE (rd, 4, 16)
+						| ENCODE (operand.reg, 4, 8)
+						| ENCODE (rn, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_umull (uint32_t *buf, uint8_t cond, uint8_t rdlo, uint8_t rdhi,
+		    uint8_t rn, uint8_t rm)
+{
+  return arm_emit_arm_data_processing_reg (buf, ARM_UMULL, cond, 0,
+					   (ENCODE (rdhi, 4, 16)
+					    | ENCODE (rdlo, 4, 12)
+					    | ENCODE (rm, 4, 8)
+					    | ENCODE (rn, 4, 0)));
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_lsl (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+
+      return arm_emit_arm_data_processing_reg (buf, ARM_LSL, cond, 0,
+					       (ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 8)
+						| ENCODE (rn, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_lsr (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+
+      return arm_emit_arm_data_processing_reg (buf, ARM_LSR, cond, 0,
+					       (ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 8)
+						| ENCODE (rn, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_asr (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_ASR, cond, 0,
+					       (ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 8)
+						/* Register op.  */
+						| ENCODE (1, 1, 4)
+						| ENCODE (rn, 4, 0)));
+    }
+  else if (operand.type == OPERAND_IMMEDIATE)
+    {
+      return arm_emit_arm_data_processing_imm (buf,
+					       (ARM_ASR
+						| ENCODE (0, 1, 20)
+						| ENCODE (rd, 4, 12)),
+					       cond, 0,
+					       (ENCODE (operand.imm, 5, 7)
+						| ENCODE (rn, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_and (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_AND, cond, 0,
+					       (ENCODE (rn, 4, 16)
+						| ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_orr (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_ORR, cond, 0,
+					       (ENCODE (rn, 4, 16)
+						| ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+int arm_emit_arm_orr_reg_shifted (uint32_t *buf, uint8_t cond, uint8_t rd,
+				  uint8_t rn, uint8_t rm, uint8_t shift,
+				  uint8_t rs)
+{
+  return arm_emit_arm_insn (buf, (ARM_ORR
+				  | ENCODE (cond, 4, 28)
+				  | ENCODE (0, 1, 20)
+				  | ENCODE (rn, 4, 16)
+				  | ENCODE (rd, 4, 12)
+				  | ENCODE (rs, 4, 8)
+				  | ENCODE (shift, 2, 5)
+				  | ENCODE (1, 1, 4)
+				  | ENCODE (rm, 4, 0)));
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_eor (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_EOR, cond, 0,
+					       (ENCODE (rn, 4, 16)
+						| ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
+
+/* See arm-insn-emit.h  */
+
+int
+arm_emit_arm_mvn (uint32_t *buf, uint8_t cond, uint8_t rd,
+		  struct arm_operand operand)
+{
+  if (operand.type == OPERAND_REGISTER)
+    {
+      return arm_emit_arm_data_processing_reg (buf, ARM_MVN, cond, 0,
+					       (ENCODE (rd, 4, 12)
+						| ENCODE (operand.reg, 4, 0)));
+    }
+  else
+    {
+      throw_error (NOT_SUPPORTED_ERROR,
+		   _("Unimplemented instruction encoding."));
+    }
+}
diff --git a/gdb/arch/arm-insn-emit.h b/gdb/arch/arm-insn-emit.h
new file mode 100644
index 0000000..bcb216d
--- /dev/null
+++ b/gdb/arch/arm-insn-emit.h
@@ -0,0 +1,1087 @@
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 ARM_INSN_H
+#define ARM_INSN_H 1
+
+/* List of the ARM opcodes we need.  */
+
+enum arm_opcodes
+  {
+    ARM_ADC     = 0x00A00000,
+    ARM_ADD     = 0x00800000,
+    ARM_AND     = 0x00000000,
+    ARM_ASR     = 0x01A00040,
+    ARM_B       = 0x0A000000,
+    ARM_BIC     = 0x03C00000,
+    ARM_BLX     = 0x012FFF30,
+    ARM_CMP     = 0x01500000,
+    ARM_DMB     = 0xF57FF050,
+    ARM_EOR     = 0x00200000,
+    ARM_LDR     = 0x04100000,
+    ARM_LDRB    = 0x04500000,
+    ARM_LDRH    = 0x005000B0,
+    ARM_LDRD    = 0x004000D0,
+    ARM_LDREX   = 0x01900F9F,
+    ARM_LSL     = 0x01A00010,
+    ARM_LSR     = 0x01A00030,
+    ARM_MOV     = 0x01A00000,
+    ARM_MOVT    = 0x03400000,
+    ARM_MOVW    = 0x03000000,
+    ARM_MRS     = 0x010F0000,
+    ARM_MSR     = 0x0120F000,
+    ARM_MUL     = 0x00000090,
+    ARM_MVN     = 0x01E00000,
+    ARM_NOP     = 0x0320F000,
+    ARM_ORR     = 0x01800000,
+    ARM_POP_A1  = 0x08BD0000,
+    ARM_POP_A2  = 0x049D0004,
+    ARM_PUSH_A1 = 0x092D0000,
+    ARM_PUSH_A2 = 0x052D0004,
+    ARM_RSB     = 0x00600000,
+    ARM_SBC     = 0x00C00000,
+    ARM_SBFX    = 0x07A00050,
+    ARM_STR     = 0x04000000,
+    ARM_STREX   = 0x01800F90,
+    ARM_SUB     = 0x00400000,
+    ARM_UBFX    = 0x07E00050,
+    ARM_UMULL   = 0x00800090,
+    ARM_VPOP    = 0x0CBD0B00,
+    ARM_VPUSH   = 0x0D2D0B00,
+  };
+
+/* List of the Thumb opcodes we need.  */
+
+enum thumb_opcodes
+  {
+    THUMB_ADD_SP  = 0xB000,
+    THUMB_BLX     = 0x4780,
+    THUMB_B       = 0xD000,
+    THUMB_BIC     = 0xF0200000,
+    THUMB_BW      = 0xF0008000,
+    THUMB_CMP     = 0x2800,
+    THUMB_CMPW    = 0xF1B00F00,
+    THUMB_DMB     = 0xF3BF8F50,
+    THUMB_LDR     = 0xF1A00000,
+    THUMB_LDREX   = 0xE8500F00,
+    THUMB_MOVT    = 0xF2C00000,
+    THUMB_MOVW    = 0xF2400000,
+    THUMB_MOV     = 0x4600,
+    THUMB_MRS     = 0xF3EF8000,
+    THUMB_MSR     = 0xF3808000,
+    THUMB_POP     = 0xBC00,
+    THUMB_POPW    = 0xE8BD0000,
+    THUMB_PUSH_T1 = 0xB400,
+    THUMB_PUSH_T2 = 0xE92D0000,
+    THUMB_SBFX    = 0XF3400000,
+    THUMB_STR     = 0x6000,
+    THUMB_STREX   = 0xE8400000,
+    THUMB_VPOP    = 0xECBD0B00,
+    THUMB_VPUSH   = 0xED2D0B00,
+  };
+
+struct arm_operand
+{
+  /* Type of the operand.  */
+  enum arm_operand_type type;
+
+  /* Value of the operand according to the type.  */
+  union
+  {
+    uint32_t imm;
+    uint8_t reg;
+    struct arm_memory_operand mem;
+  };
+};
+
+enum arm_shifts
+  {
+    LSL = 0x0, /* Logical shift left.  */
+    LSR = 0x1, /* Logical shift right.  */
+    ASR = 0x2, /* Arithmetic shift right.  */
+  };
+
+/* Helper function to create an immediate operand
+
+   Example:
+
+     p += emit_mov (p, r0, immediate_operand (12));  */
+
+struct arm_operand immediate_operand (uint32_t imm);
+
+/* Helper function to create a register operand.
+
+   Example:
+
+     p += emit_mov (p, r0, register_operand (r1));  */
+
+struct arm_operand register_operand (uint8_t reg);
+
+/* Helper function to create an memory operand.
+
+   Example:
+
+     p += emit_mov (p, r0, immediate_operand (12));  */
+
+struct arm_operand memory_operand (struct arm_memory_operand mem);
+
+/* Encode a register list bitfield, using a consecutive list of bits from
+   FROM with length LENGTH and using an inital value of INITIAL. Max 16
+   bits.  */
+
+uint16_t encode_register_list (uint8_t from, uint8_t length, uint16_t initial);
+
+/* Return the distance in bytes from FROM to TO and adjusted for prefetch.  */
+
+uint32_t arm_arm_branch_relative_distance (CORE_ADDR from, CORE_ADDR to);
+
+/* Return the distance in bytes from FROM to TO and adjusted for prefetch.  */
+
+uint32_t arm_thumb_branch_relative_distance (CORE_ADDR from, CORE_ADDR to);
+
+/* Return the distance in bytes from FROM to TO , adjusted for prefetch
+   and for alignement when switching from ARM mode to Thumb mode.  */
+
+uint32_t arm_thumb_to_arm_branch_relative_distance (CORE_ADDR from,
+						    CORE_ADDR to);
+
+/* Return the offset is bytes adjusted for prefetch.  */
+
+uint32_t arm_arm_branch_adjusted_offset (uint32_t offset);
+
+/* Return the offset in bytes adjusted for prefetch.  */
+
+uint32_t arm_thumb_branch_adjusted_offset (uint32_t offset);
+
+/* Return whether it's possible to jump from FROM to TO using a relative
+   branch in arm mode.  */
+
+int arm_arm_is_reachable (CORE_ADDR from, CORE_ADDR to);
+
+/* Return whether it's possible to jump from FROM to TO using a relative
+   branch in thumb mode.  */
+
+int arm_thumb_is_reachable (CORE_ADDR from, CORE_ADDR to);
+
+/* Write arm instructions to move the 32bit value VAL into register REG.  */
+
+int arm_emit_arm_mov_32 (uint32_t *mem, int reg, uint32_t val);
+
+/* Write thumb instructions to move the 32bit value VAL into register REG.  */
+
+int arm_emit_thumb_mov_32 (uint16_t *mem, int reg, uint32_t val);
+
+/* Write an ARM B instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   B<c> <label>
+
+   COND is the conditionial instruction flag.
+   REL is the relative offset of the label.  */
+
+int arm_emit_arm_b (uint32_t *buf, uint8_t cond, uint32_t rel);
+
+/* Write an ARM BL instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   BL<c> <label>
+
+   REL is the relative offset of the label.  */
+
+int arm_emit_arm_bl (uint32_t *buf, uint8_t cond, uint32_t rel);
+
+/* Write a Thumb BL instruction into *BUF.
+
+   Encoding T1
+   BL<c> <label>
+   ARMv4T, ARMv5T*, ARMv6*, ARMv7 if J1 == J2 == 1
+   ARMv6T2, ARMv7 otherwise
+   Outside or last in IT block
+
+   REL is the relative offset of the label.  */
+
+int arm_emit_thumb_bl (uint16_t *buf, uint32_t rel);
+
+/* Write a Thumb B instruction into *BUF.
+
+   Encoding T1
+   ARMv4T, ARMv5T*, ARMv6*, ARMv7
+   B<c> <label>
+   Not permitted in IT block.
+
+   REL is the relative offset of the label.  */
+
+int arm_emit_thumb_b (uint16_t *buf, uint8_t cond, uint32_t rel);
+
+/* Write a Thumb BW instruction into *BUF.
+
+   Encoding T4
+   ARMv6T2, ARMv7
+   B<c>.W <label>
+   Outside or last in IT block
+
+   REL is the relative offset of the label.  */
+
+int arm_emit_thumb_bw (uint16_t *buf, uint32_t rel);
+
+/* Write a Thumb BW instruction into *BUF.
+
+   Encoding T3
+   ARMv6T2, ARMv7
+   B<c>.W <label>
+   Not permitted in IT block.
+
+   REL is the relative offset of the label.  */
+
+int arm_emit_thumb_bw_cond (uint16_t *buf, uint8_t cond, uint32_t rel);
+
+/* Write an ARM BLX instruction into *BUF.
+
+   Register:
+   Encoding A1
+   ARMv5T*, ARMv6*, ARMv7
+   BLX<c> <Rm>
+
+   OPERAND is the register or the immediate value that contains the branch
+   target address and instruction set selection bit.  */
+
+int arm_emit_arm_blx (uint32_t * buf, uint8_t cond, struct arm_operand operand);
+
+/* Write a Thumb BLX instruction into *BUF.
+
+   Register:
+   Encoding T1
+   ARMv5T*, ARMv6*, ARMv7
+   BLX<c> <Rm>
+   Outside or last in IT block
+
+   Immediate:
+   Encoding T2
+   BLX<c> <label>
+   ARMv5T*, ARMv6*, ARMv7 if J1 == J2 == 1
+   ARMv6T2, ARMv7 otherwise
+   Outside or last in IT block
+
+   OPERAND is the register or the immediate value that contains the branch
+   target address and instruction set selection bit.  */
+
+int arm_emit_thumb_blx (uint16_t *buf, struct arm_operand operand);
+
+/* Write an ARM MOVW (Immediate) instruction into *BUF.
+
+   Encoding A2
+   ARMv6T2, ARMv7
+   MOVW<c> <Rd>, #<imm16>
+
+   RD is the destination register.
+   OPERAND is the immediate value to be placed in RD.
+*/
+
+int arm_emit_arm_movw (uint32_t *buf, uint8_t cond, uint8_t rd,
+		       struct arm_operand operand);
+
+/* Write a Thumb MOVW (Immediate) instruction into *BUF.
+
+   Encoding T3
+   ARMv6T2, ARMv7
+   MOVW<c> <Rd>, #<imm16>
+
+   RD is the destination register.
+   OPERAND is the immediate value to be placed in RD.  */
+
+int arm_emit_thumb_movw (uint16_t *buf, uint8_t rd, struct arm_operand operand);
+
+/* Write an ARM MOV instruction into *BUF.
+
+   Encoding A1
+
+   Immediate:
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   MOV{S}<c> <Rd>, #<const>
+
+   Register:
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   MOV{S}<c> <Rd>, <Rm>
+
+   RD is the destination register.
+   OPERAND is the immediate value or source register.  */
+
+int arm_emit_arm_mov (uint32_t *buf, uint8_t cond, uint8_t rd,
+		      struct arm_operand operand);
+
+/* Write an ARM MOVT instruction into *BUF.
+
+   Encoding A1
+   ARMv6T2, ARMv7
+   MOVT<c> <Rd>, #<imm16>
+
+   RD is the destination register.
+   OPERAND is the immediate value to be placed in RD.  */
+
+int arm_emit_arm_movt (uint32_t *buf, uint8_t cond, uint8_t rd,
+		       struct arm_operand operand);
+
+/* Write a Thumb MOVT instruction into *BUF.
+
+   Encoding T1
+   ARMv6T2, ARMv7
+   MOVT<c> <Rd>, #<imm16>
+
+   RD is the destination register.
+   OPERAND is the immediate value to be placed in RD.  */
+
+int arm_emit_thumb_movt (uint16_t *buf, uint8_t rd,
+			 struct arm_operand operand);
+
+/* Write an ARM VPUSH instruction into *BUF.
+
+   Encoding A1
+   VFPv2, VFPv3, VFPv4, Advanced SIMD
+   VPUSH<c> <list>
+   <list> is consecutive 64-bit registers.
+
+   COND is the conditionial instruction flag.
+   RS is the starting register.
+   LEN is the length of the register list.  */
+
+int arm_emit_arm_vpush (uint32_t *buf, uint8_t cond, uint8_t rs, uint8_t len);
+
+/* Write a Thumb VPUSH instruction into *BUF.
+
+   Encoding T1
+   VFPv2, VFPv3, VFPv4, Advanced SIMD
+   VPUSH<c> <list>
+   <list> is consecutive 64-bit registers.
+
+   COND is the conditionial instruction flag.
+   RS is the starting register.
+   LEN is the length of the register list.  */
+
+int arm_emit_thumb_vpush (uint16_t *buf, uint8_t rs, uint8_t len);
+
+/* Write an ARM PUSH instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   PUSH<c> <registers>
+   <registers> contains more than one register
+
+   COND is the conditionial instruction flag.
+   REGISTER_LIST is the register list bitfield.  */
+
+int arm_emit_arm_push_list (uint32_t *buf, uint8_t cond,
+			    uint16_t register_list);
+
+/* Write a Thumb PUSH instruction into *BUF.
+
+   Encoding T2
+   ARMv6T2, ARMv7
+   PUSH<c>.W <registers>
+   <registers> contains more than one register
+
+   REGISTER_LIST is the register_list bitfield.
+   LR denotes the presence of LR in the list.  */
+
+int arm_emit_thumb_push_list (uint16_t *buf, uint16_t register_list,
+			      uint8_t lr);
+
+/* Write an ARM PUSH instruction into *BUF.
+
+   Encoding A2
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   PUSH<c> <registers>
+   <registers> contains one register, <Rt>
+
+   RT is the register to push.
+   COND is the conditionial instruction flag.  */
+
+int arm_emit_arm_push_one (uint32_t *buf, uint8_t cond, uint8_t rt);
+
+/* Write a Thumb PUSH instruction into *BUF.
+
+   Encoding T1
+   ARMv4T, ARMv5T*, ARMv6*, ARMv7
+   PUSH<c> <registers>
+
+   REGISTER_LIST is the registers list to push.
+   LR denotes the presence of LR in the list.  */
+
+int arm_emit_thumb_push_one (uint16_t *buf, uint8_t register_list, uint8_t lr);
+
+/* Write an ARM MRS instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   MRS<c> <Rd>, <spec_reg>
+
+   RD is the destination register.  */
+
+int arm_emit_arm_mrs (uint32_t *buf, uint8_t cond, uint8_t rd);
+
+/* Write a Thumb MRS instruction into *BUF.
+
+   Encoding T1
+   ARMv6T2, ARMv7
+   MRS<c> <Rd>, <spec_reg>
+
+   RD is the destination register.  */
+
+int arm_emit_thumb_mrs (uint16_t *buf, uint8_t rd);
+
+/* Write a Thumb MOV Register instruction into *BUF.
+
+   Encoding T1
+   MOV<c> <Rd>, <Rm>
+   ARMv6*, ARMv7 if <Rd> and <Rm> both from R0-R7
+   ARMv4T, ARMv5T*, ARMv6*, ARMv7 otherwise
+   If <Rd> is the PC, must be outside or last in IT block.
+
+   RD is the destination register.
+   OPERAND is the source register.  */
+
+int arm_emit_thumb_mov (uint16_t *buf, uint8_t rd, struct arm_operand operand);
+
+/* Write an ARM DMB instruction into *BUF.
+
+   Encoding A1
+   ARMv7
+   DMB <option>
+
+   option is ommited to mean SY.  */
+
+int arm_emit_arm_dmb (uint32_t *buf);
+
+/* Write a Thumb DMB instruction into *BUF.
+
+   Encoding T1
+   ARMv7
+   DMB <option>
+
+   option is ommited to mean SY.  */
+
+int arm_emit_thumb_dmb (uint16_t *buf);
+
+/* Write an ARM LDREX instruction into *BUF.
+   Encoding A1
+   ARMv6*, ARMv7
+   LDREX<c> <Rt>, [<Rn>]
+
+   COND is the conditionial instruction flag.
+   RT is the destination register.
+   RN is the base register.  */
+
+int arm_emit_arm_ldrex (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn);
+
+/* Write a Thumb LDREX instruction into *BUF.
+
+   Encoding T1
+   ARMv6T2, ARMv7
+   LDREX<c> <Rt>, [<Rn>{, #<imm>}]
+
+   RT is the destination register.
+   RN is the base register.
+
+   OPERAND is the immediate offset added to the value of RN to form the
+   address.  */
+
+int arm_emit_thumb_ldrex (uint16_t *buf, int8_t rt, uint8_t rn,
+			  struct arm_operand operand);
+
+/* Write an ARM CMP instruction into *BUF.
+
+   Immediate:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   CMP<c> <Rn>, #<const>
+
+   Register:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   CMP<c> <Rn>, <Rm>{, <shift>}
+
+   COND is the conditionial instruction flag.
+   RN is the base register.
+   OPERAND is the immediate value to be compared with the value obtained
+   from RN.  */
+
+int arm_emit_arm_cmp (uint32_t *buf, uint8_t cond, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write a Thumb CMP (immediate) instruction into *BUF.
+
+   Encoding T1
+   ARMv4T, ARMv5T*, ARMv6*, ARMv7
+   CMP<c> <Rn>, #<imm8>
+
+   RN is the base register.
+   OPERAND is the immediate value to be compared with the value obtained
+   from RN.  */
+
+int arm_emit_thumb_cmp (uint16_t *buf, uint8_t rn, struct arm_operand operand);
+
+/* Write a Thumb CMP.w (immediate) instruction into *BUF.
+
+   Encoding T2
+   ARMv6T2, ARMv7
+   CMP<c>.W <Rn>, #<const>
+
+   RN is the base register.
+   OPERAND is the immediate value to be compared with the value obtained
+   from RN.  */
+
+int arm_emit_thumb_cmpw (uint16_t *buf, uint8_t rn, struct arm_operand operand);
+
+/* Write an ARM BIC (immediate) instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   BIC{S}<c> <Rd>, <Rn>, #<const>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the base register.
+   OPERAND is the immediate value to be bitwise inverted and ANDed with
+   the value obtained from RN.  */
+
+int arm_emit_arm_bic (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write a Thumb BIC (immediate) instruction into *BUF.
+
+   Encoding T1
+   ARMv6T2, ARMv7
+   BIC{S}<c> <Rd>, <Rn>, #<const>
+
+   RD is the destination register.
+   RN is the base register.
+   OPERAND is the immediate value to be bitwise inverted and ANDed with
+   the value obtained from RN.  */
+
+int arm_emit_thumb_bic (uint16_t *buf, uint8_t rd, uint8_t rn,
+			struct arm_operand operand);
+
+/* Write an ARM STREX instruction into *BUF.
+
+   Encoding A1
+   ARMv6*, ARMv7
+   STREX<c> <Rd>, <Rt>, [<Rn>]
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RT is the source register.
+   RN is the base register.  */
+
+int arm_emit_arm_strex (uint32_t *buf, uint8_t cond, uint8_t rd,
+			uint8_t rt, uint8_t rn);
+
+/* Write a Thumb STREX (immediate) instruction into *BUF.
+
+   Encoding T1
+   ARMv6T2, ARMv7
+   STREX<c> <Rd>, <Rt>, [<Rn>{, #<imm>}]
+
+   RD is the destination register.
+   RT is the source register.
+   RN is the base register.
+   OPERAND is the immediate offset added to the value of RN to form the
+   address.  */
+
+int arm_emit_thumb_strex (uint16_t *buf, uint8_t rd, uint8_t rt, uint8_t rn,
+			  struct arm_operand operand);
+
+/* Write an ARM STR (immediate) instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   STR<c> <Rt>, [<Rn>{, #+/-<imm12>}]
+   STR<c> <Rt>, [<Rn>], #+/-<imm12>
+   STR<c> <Rt>, [<Rn>, #+/-<imm12>]!
+
+   COND is the conditionial instruction flag.
+   RT is the source register.
+   RN is the base register.
+   OPERAND is the immediate offset used for forming the address.  */
+
+int arm_emit_arm_str (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write a Thumb STR (immediate) instruction into *BUF.
+
+   Encoding T1
+   ARMv4T, ARMv5T*, ARMv6*, ARMv7
+   STR<c> <Rt>, [<Rn>{, #<imm>}]
+
+   RT is the source register.
+   RN is the base register.
+   OPERAND is the immediate offset used for forming the address.  */
+
+int arm_emit_thumb_str (uint16_t *buf, uint8_t rt, uint8_t rn,
+			struct arm_operand operand);
+
+/* Write an ARM ADD instruction into *BUF.
+
+   Immediate:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   ADD{S}<c> <Rd>, <Rn>, #<const>
+
+   Register:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   ADD{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+
+   COND is the conditionial instruction flag.
+   FLAGS update the flags if set to 1.
+   RD is the destination register.
+   RN is the base register.
+   OPERAND is the operand to be added to the value obtained from RN.  */
+
+int arm_emit_arm_add (uint32_t *buf, uint8_t cond, uint8_t flags, uint8_t rd,
+		      uint8_t rn, struct arm_operand operand);
+
+/* Write an ARM ADC instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   ADC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the base register.
+   OPERAND is the operand to be added to the value obtained from RN.  */
+
+int arm_emit_arm_adc (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write a Thumb ADD (SP plus immediate) instruction into *BUF.
+
+   Encoding T2
+   ARMv4T, ARMv5T*, ARMv6*, ARMv7
+   ADD<c> SP, SP, #<imm>
+
+   OPERAND is the immediate value to be added to the value obtained from SP.  */
+
+int arm_emit_thumb_add_sp (uint16_t *buf, struct arm_operand operand);
+
+/* Write an ARM POP instruction into *BUF.
+
+   Encoding A2
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   POP<c> <registers>
+   <registers> contains one register, <Rt>
+
+   RT is the register to be loaded.  */
+
+int arm_emit_arm_pop_one (uint32_t *buf, uint8_t cond, uint8_t rt);
+
+/* Write an ARM POP instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   POP<c> <registers>
+   <registers> contains more than one register
+
+   RT is the register to be loaded.  */
+
+int arm_emit_arm_pop_list (uint32_t *buf, uint8_t cond, uint16_t register_list);
+
+/* Write a Thumb POP instruction into *BUF.
+
+   Encoding T1
+   ARMv4T, ARMv5T*, ARMv6*, ARMv7
+   POP<c> <registers>
+
+   REGISTER_LIST is a list of one or more registers to be loaded.
+   PC is a flag that triggers the addition of the PC register to the list.  */
+
+int arm_emit_thumb_pop (uint16_t *buf, uint8_t register_list, uint8_t pc);
+
+/* Write a Thumb POPW instruction into *BUF.
+
+   Encoding T2
+   ARMv6T2, ARMv7
+   POP<c>.W <registers>
+   <registers> contains more than one register
+
+   REGISTER_LIST is a list of one or more registers to be loaded.
+   PC is a flag that triggers the addition of the PC register to the list.
+   LR is a flag that triggers the addition of the LR register to the list.  */
+
+int arm_emit_thumb_popw_list (uint16_t *buf, uint16_t register_list, uint8_t pc,
+			      uint8_t lr);
+
+/* Write an ARM MSR instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   MRS<c> <Rd>, <spec_reg>
+
+   RN is the ARM core register to be transferred to <spec_reg>.  */
+
+int arm_emit_arm_msr (uint32_t *buf, uint8_t cond, uint8_t rn);
+
+/* Write a Thumb MRS instruction into *BUF.
+
+   Encoding T1
+   ARMv6T2, ARMv7
+   MRS<c> <Rd>, <spec_reg>
+
+   RN is the ARM core register to be transferred to <spec_reg>.  */
+
+int arm_emit_thumb_msr (uint16_t *buf, uint8_t rn);
+
+/* Write an ARM VPOP instruction into *BUF.
+
+   Encoding A1
+   VFPv2, VFPv3, VFPv4, Advanced SIMD
+   VPOP <list>
+
+   <list> is consecutive 64-bit registers
+
+   COND is the conditionial instruction flag.
+   RS is the starting register.
+   LEN is the length of the register list.  */
+
+int arm_emit_arm_vpop (uint32_t *buf, uint8_t cond, uint8_t rs, uint8_t len);
+
+/* Write a Thumb VPOP instruction into *BUF.
+
+   Encoding T1
+   VFPv2, VFPv3, VFPv4, Advanced SIMD
+   VPOP <list>
+
+   COND is the conditionial instruction flag.
+   RS is the starting register.
+   LEN is the length of the register list.  */
+
+int arm_emit_thumb_vpop (uint16_t *buf, uint8_t rs, uint8_t len);
+
+/* Write an ARM LDR instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   LDR<c> <Rt>, [<Rn>{, #+/-<imm12>}]
+   LDR<c> <Rt>, [<Rn>], #+/-<imm12>
+   LDR<c> <Rt>, [<Rn>, #+/-<imm12>]!
+
+   COND is the conditionial instruction flag.
+   RT is the destination register.
+   RN is the base register.
+   OPERAND is the offset used for forming the address.  */
+
+int arm_emit_arm_ldr (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		      struct arm_memory_operand operand);
+
+/* Write an ARM LDRB instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   LDRB<c> <Rt>, [<Rn>{, #+/-<imm12>}]
+   LDRB<c> <Rt>, [<Rn>], #+/-<imm12>
+   LDRB<c> <Rt>, [<Rn>, #+/-<imm12>]!
+
+   COND is the conditionial instruction flag.
+   RT is the destination register.
+   RN is the base register.
+   OPERAND is the offset used for forming the address.  */
+
+int arm_emit_arm_ldrb (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		       struct arm_memory_operand operand);
+
+/* Write an ARM LDRH instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   LDRH<c> <Rt>, [<Rn>{, #+/-<imm8>}]
+   LDRH<c> <Rt>, [<Rn>], #+/-<imm8>
+   LDRH<c> <Rt>, [<Rn>, #+/-<imm8>]!
+
+   COND is the conditionial instruction flag.
+   RT is the destination register.
+   RN is the base register.
+   OPERAND is the offset used for forming the address.  */
+
+int arm_emit_arm_ldrh (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		       struct arm_memory_operand operand);
+
+/* Write an ARM LDRD instruction into *BUF.
+
+   Encoding A1
+   ARMv5TE*, ARMv6*, ARMv7
+   LDRD<c> <Rt>, <Rt2>, [<Rn>{, #+/-<imm8>}]
+   LDRD<c> <Rt>, <Rt2>, [<Rn>], #+/-<imm8>
+   LDRD<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm8>]!
+
+   COND is the conditionial instruction flag.
+   RT is the frist destination register, second will automatically be RT+1.
+   RN is the base register.
+   OPERAND is the offset used for forming the address.  */
+
+int arm_emit_arm_ldrd (uint32_t *buf, uint8_t cond, uint8_t rt, uint8_t rn,
+		       struct arm_memory_operand operand);
+
+/* Write an ARM SBFX instruction into *BUF.
+
+   Encoding A1
+   ARMv6T2, ARMv7
+   SBFX<c> <Rd>, <Rn>, #<lsb>, #<width>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN the first operand register.
+   LSB is the bit number of the least significant bit in the field, in the
+   range 0-31.
+   WIDTH is the width of the field, in the range 1 to 32- <LSB>.
+   OPERAND is the offset used for forming the address.  */
+
+int arm_emit_arm_sbfx (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		       uint32_t lsb, uint32_t width);
+
+/* Write an ARM NOP instruction into *BUF.
+
+   Encoding A1
+   ARMv6K, ARMv6T2, ARMv7
+   NOP<c>
+
+   COND is the conditionial instruction flag.  */
+
+int arm_emit_arm_nop (uint32_t *buf, uint8_t cond);
+
+/* Write an ARM UBFX instruction into *BUF.
+
+   Encoding A1
+   ARMv6T2, ARMv7
+   UBFX<c> <Rd>, <Rn>, #<lsb>, #<width>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   LSB is the bit number of the least significant bit in the field, in the
+   range 0-31. This determines the required value of lsbit .
+   WIDTH is the width of the field, in the range 1 to 32- LSB.  */
+
+int arm_emit_arm_ubfx (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		       uint8_t lsb, uint8_t width);
+
+/* Write an ARM SUB instruction into *BUF.
+
+   Register:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   SUB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+
+   Immediate:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   SUB{S}<c> <Rd>, <Rn>, #<const>
+
+   COND is the conditionial instruction flag.
+   FLAGS update the flags if set to 1.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_sub (uint32_t *buf, uint8_t cond, uint8_t flags, uint8_t rd,
+		      uint8_t rn, struct arm_operand operand);
+
+/* Write an ARM RSB instruction into *BUF.
+
+   Register:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   RSB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+
+   Immediate:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   RSB{S}<c> <Rd>, <Rn>, #<const>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_rsb (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write an ARM SBC instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   SBC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+
+   COND is the conditionial instruction flag.
+   FLAGS update the flags if set to 1.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_sbc (uint32_t *buf, uint8_t cond, uint8_t flags, uint8_t rd,
+		      uint8_t rn, struct arm_operand operand);
+
+/* Write an ARM MUL instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   MUL{S}<c> <Rd>, <Rn>, <Rm>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_mul (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write an ARM UMULL instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   UMULL{S}<c> <RdLo>, <RdHi>, <Rn>, <Rm>
+
+   COND is the conditionial instruction flag.
+   RDLO is the lower 32 bits of the result.
+   RDHI is the upper 32 bits of the result.
+   RN is the first operand register.
+   RM is the second operand register.  */
+
+int arm_emit_arm_umull (uint32_t *buf, uint8_t cond, uint8_t rdlo,
+			uint8_t rdhi, uint8_t rn, uint8_t rm);
+
+/* Write an ARM LSL instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   LSL{S}<c> <Rd>, <Rn>, <Rm>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_lsl (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write an ARM LSR instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   LSR{S}<c> <Rd>, <Rn>, <Rm>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_lsr (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write an ARM ASR instruction into *BUF.
+
+   Register:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   ASR{S}<c> <Rd>, <Rn>, <Rm>
+
+   Immediate:
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   ASR{S}<c> <Rd>, <Rm>, #<imm>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_asr (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write an ARM AND instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   AND{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_and (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write an ARM ORR instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   ORR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_orr (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write an ARM ORR (register-shifted register) instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   ORR{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   RM is the register that is shifted and used as the second operand.
+   SHIFT is the type of shift to apply to the value read from <Rm>.
+   RS is the register whose bottom byte contains the amount to shift by.  */
+
+int arm_emit_arm_orr_reg_shifted (uint32_t *buf, uint8_t cond, uint8_t rd,
+				  uint8_t rn, uint8_t rm, uint8_t shift,
+				  uint8_t rs);
+
+/* Write an ARM EOR instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   EOR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   RN is the first operand register.
+   OPERAND is used as the second operand.  */
+
+int arm_emit_arm_eor (uint32_t *buf, uint8_t cond, uint8_t rd, uint8_t rn,
+		      struct arm_operand operand);
+
+/* Write an ARM MVN instruction into *BUF.
+
+   Encoding A1
+   ARMv4*, ARMv5T*, ARMv6*, ARMv7
+   MVN{S}<c> <Rd>, <Rm>{, <shift>}
+
+   COND is the conditionial instruction flag.
+   RD is the destination register.
+   OPERAND is used as the operand.  */
+
+int arm_emit_arm_mvn (uint32_t *buf, uint8_t cond, uint8_t rd,
+		      struct arm_operand operand);
+
+#endif /* ARM_INSN_H */
diff --git a/gdb/arch/arm-insn-utils.c b/gdb/arch/arm-insn-utils.c
new file mode 100644
index 0000000..801bee1
--- /dev/null
+++ b/gdb/arch/arm-insn-utils.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 2015-2016 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+   This file is part of GDB.
+
+   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 "common-defs.h"
+#include "arm-insn-utils.h"
+
+/* See arm-insn-utils.h.  */
+
+struct arm_memory_operand
+offset_memory_operand (int32_t offset)
+{
+  return (struct arm_memory_operand) { MEMORY_OPERAND_OFFSET, offset };
+}
+
+/* See arm-insn-utils.h.  */
+
+struct arm_memory_operand
+preindex_memory_operand (int32_t index)
+{
+  return (struct arm_memory_operand) { MEMORY_OPERAND_PREINDEX, index };
+}
+
+/* See arm-insn-utils.h.  */
+
+struct arm_memory_operand
+postindex_memory_operand (int32_t index)
+{
+  return (struct arm_memory_operand) { MEMORY_OPERAND_POSTINDEX, index };
+}
diff --git a/gdb/arch/arm-insn-utils.h b/gdb/arch/arm-insn-utils.h
new file mode 100644
index 0000000..6b47438
--- /dev/null
+++ b/gdb/arch/arm-insn-utils.h
@@ -0,0 +1,80 @@
+/* Copyright (C) 2009-2016 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+/* Helper macro to mask and shift a value into a bitfield.  */
+
+#ifndef ARM_INSN_UTILS_H
+#define ARM_INSN_UTILS_H 1
+
+#define ENCODE(val, size, offset) \
+  ((uint32_t) ((val & ((1ULL << size) - 1)) << offset))
+
+enum arm_memory_operand_type
+{
+  MEMORY_OPERAND_OFFSET,
+  MEMORY_OPERAND_PREINDEX,
+  MEMORY_OPERAND_POSTINDEX,
+};
+
+/* Representation of a memory operand, used for load and store
+   instructions.
+
+   The types correspond to the following variants:
+
+   MEMORY_OPERAND_OFFSET:    LDR rt, [rn, #offset]
+   MEMORY_OPERAND_PREINDEX:  LDR rt, [rn, #index]!
+   MEMORY_OPERAND_POSTINDEX: LDR rt, [rn], #index  */
+
+struct arm_memory_operand
+{
+  /* Type of the operand.  */
+  enum arm_memory_operand_type type;
+
+  /* Index from the base register.  */
+  int32_t index;
+};
+
+enum arm_operand_type
+{
+  OPERAND_IMMEDIATE,
+  OPERAND_REGISTER,
+  OPERAND_MEMORY,
+};
+
+/* Helper function to create an offset memory operand.
+
+   For example:
+   p += emit_ldr (p, x0, sp, offset_memory_operand (16));  */
+
+struct arm_memory_operand offset_memory_operand (int32_t offset);
+
+/* Helper function to create a pre-index memory operand.
+
+   For example:
+   p += emit_ldr (p, x0, sp, preindex_memory_operand (16));  */
+
+struct arm_memory_operand preindex_memory_operand (int32_t index);
+
+/* Helper function to create a post-index memory operand.
+
+   For example:
+   p += emit_ldr (p, x0, sp, postindex_memory_operand (16));  */
+
+struct arm_memory_operand postindex_memory_operand (int32_t index);
+
+#endif
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index e447356..902d043 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -38,7 +38,8 @@ esac
 case "${targ}" in
 aarch64*-*-elf | aarch64*-*-rtems*)
 	# Target: AArch64 embedded system
-	gdb_target_obs="aarch64-tdep.o aarch64-newlib-tdep.o aarch64-insn.o"
+	gdb_target_obs="aarch64-tdep.o aarch64-newlib-tdep.o aarch64-insn.o \
+			arm-insn-utils.o"
 	;;
 
 aarch64*-*-linux*)
@@ -47,7 +48,7 @@ aarch64*-*-linux*)
 			arm.o arm-linux.o arm-get-next-pcs.o arm-tdep.o \
 			arm-linux-tdep.o \
 			glibc-tdep.o linux-tdep.o solib-svr4.o \
-			symfile-mem.o linux-record.o"
+			symfile-mem.o linux-record.o arm-insn-utils.o"
 	build_gdbserver=yes
 	;;
 
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 2be61ef..271f804 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -185,7 +185,8 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/common/btrace-common.c \
 	$(srcdir)/common/fileio.c $(srcdir)/nat/linux-namespaces.c \
 	$(srcdir)/arch/arm.c $(srcdir)/common/common-regcache.c \
-	$(srcdir)/arch/arm-linux.c $(srcdir)/arch/arm-get-next-pcs.c
+	$(srcdir)/arch/arm-linux.c $(srcdir)/arch/arm-get-next-pcs.c \
+	$(srcdir)/arch/arm-insn-emit.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -727,6 +728,9 @@ arm-linux.o: ../arch/arm-linux.c
 arm-get-next-pcs.o: ../arch/arm-get-next-pcs.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+arm-insn-emit.o: ../arch/arm-insn-emit.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
 
 # Native object files rules from ../nat
 
@@ -785,6 +789,10 @@ aarch64-insn.o: ../arch/aarch64-insn.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+arm-insn-utils.o: ../arch/arm-insn-utils.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 aarch64.c : $(srcdir)/../regformats/aarch64.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/aarch64.dat aarch64.c
 reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh)
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index fe53e03..34d4be8 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -56,6 +56,7 @@ case "${target}" in
 			srv_tgtobj="${srv_tgtobj} arm.o"
 			srv_tgtobj="$srv_tgtobj aarch64-linux.o"
 			srv_tgtobj="$srv_tgtobj aarch64-insn.o"
+			srv_tgtobj="$srv_tgtobj arm-insn-utils.o"
 			srv_tgtobj="${srv_tgtobj} $srv_linux_obj"
 			srv_xmlfiles="aarch64.xml"
 			srv_xmlfiles="${srv_xmlfiles} aarch64-core.xml"
@@ -75,6 +76,8 @@ case "${target}" in
 			srv_tgtobj="${srv_tgtobj} arm.o"
 			srv_tgtobj="${srv_tgtobj} arm-linux.o"
 			srv_tgtobj="${srv_tgtobj} arm-get-next-pcs.o"
+			srv_tgtobj="${srv_tgtobj} arm-insn-emit.o"
+			srv_tgtobj="${srv_tgtobj} arm-insn-utils.o"
 			srv_xmlfiles="arm-with-iwmmxt.xml"
 			srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv2.xml"
 			srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv3.xml"
diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index da8c0cc..8aefe6b 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -23,6 +23,7 @@
 #include "linux-low.h"
 #include "nat/aarch64-linux.h"
 #include "nat/aarch64-linux-hw-point.h"
+#include "arch/arm-insn-utils.h"
 #include "arch/aarch64-insn.h"
 #include "linux-aarch32-low.h"
 #include "elf/common.h"
@@ -601,19 +602,13 @@ enum aarch64_condition_codes
   LE = 0xd,
 };
 
-enum aarch64_operand_type
-{
-  OPERAND_IMMEDIATE,
-  OPERAND_REGISTER,
-};
-
 /* Representation of an operand.  At this time, it only supports register
    and immediate types.  */
 
 struct aarch64_operand
 {
   /* Type of the operand.  */
-  enum aarch64_operand_type type;
+  enum arm_operand_type type;
 
   /* Value of the operand according to the type.  */
   union
@@ -690,39 +685,6 @@ immediate_operand (uint32_t imm)
   return operand;
 }
 
-/* Helper function to create an offset memory operand.
-
-   For example:
-   p += emit_ldr (p, x0, sp, offset_memory_operand (16));  */
-
-static struct aarch64_memory_operand
-offset_memory_operand (int32_t offset)
-{
-  return (struct aarch64_memory_operand) { MEMORY_OPERAND_OFFSET, offset };
-}
-
-/* Helper function to create a pre-index memory operand.
-
-   For example:
-   p += emit_ldr (p, x0, sp, preindex_memory_operand (16));  */
-
-static struct aarch64_memory_operand
-preindex_memory_operand (int32_t index)
-{
-  return (struct aarch64_memory_operand) { MEMORY_OPERAND_PREINDEX, index };
-}
-
-/* Helper function to create a post-index memory operand.
-
-   For example:
-   p += emit_ldr (p, x0, sp, postindex_memory_operand (16));  */
-
-static struct aarch64_memory_operand
-postindex_memory_operand (int32_t index)
-{
-  return (struct aarch64_memory_operand) { MEMORY_OPERAND_POSTINDEX, index };
-}
-
 /* System control registers.  These special registers can be written and
    read with the MRS and MSR instructions.
 
@@ -770,7 +732,7 @@ emit_load_store_pair (uint32_t *buf, enum aarch64_opcodes opcode,
 		      struct aarch64_register rt,
 		      struct aarch64_register rt2,
 		      struct aarch64_register rn,
-		      struct aarch64_memory_operand operand)
+		      struct arm_memory_operand operand)
 {
   uint32_t opc;
   uint32_t pre_index;
@@ -825,7 +787,7 @@ emit_load_store_pair (uint32_t *buf, enum aarch64_opcodes opcode,
 static int
 emit_stp (uint32_t *buf, struct aarch64_register rt,
 	  struct aarch64_register rt2, struct aarch64_register rn,
-	  struct aarch64_memory_operand operand)
+	  struct arm_memory_operand operand)
 {
   return emit_load_store_pair (buf, STP, rt, rt2, rn, operand);
 }
@@ -844,7 +806,7 @@ emit_stp (uint32_t *buf, struct aarch64_register rt,
 static int
 emit_ldp (uint32_t *buf, struct aarch64_register rt,
 	  struct aarch64_register rt2, struct aarch64_register rn,
-	  struct aarch64_memory_operand operand)
+	  struct arm_memory_operand operand)
 {
   return emit_load_store_pair (buf, LDP, rt, rt2, rn, operand);
 }
@@ -907,7 +869,7 @@ emit_stp_q_offset (uint32_t *buf, unsigned rt, unsigned rt2,
 static int
 emit_ldrh (uint32_t *buf, struct aarch64_register rt,
 	   struct aarch64_register rn,
-	   struct aarch64_memory_operand operand)
+	   struct arm_memory_operand operand)
 {
   return aarch64_emit_load_store (buf, 1, LDR, rt, rn, operand);
 }
@@ -926,7 +888,7 @@ emit_ldrh (uint32_t *buf, struct aarch64_register rt,
 static int
 emit_ldrb (uint32_t *buf, struct aarch64_register rt,
 	   struct aarch64_register rn,
-	   struct aarch64_memory_operand operand)
+	   struct arm_memory_operand operand)
 {
   return aarch64_emit_load_store (buf, 0, LDR, rt, rn, operand);
 }
@@ -947,7 +909,7 @@ emit_ldrb (uint32_t *buf, struct aarch64_register rt,
 static int
 emit_str (uint32_t *buf, struct aarch64_register rt,
 	  struct aarch64_register rn,
-	  struct aarch64_memory_operand operand)
+	  struct arm_memory_operand operand)
 {
   return aarch64_emit_load_store (buf, rt.is64 ? 3 : 2, STR, rt, rn, operand);
 }
