]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - opcodes/s12z-opc.c
gdb: Convert language skip_trampoline field to a method
[thirdparty/binutils-gdb.git] / opcodes / s12z-opc.c
index 36509b58dcd8bb52278d3d5755c6ef47c41c79ec..b68a4b815c42c69c4e4e6f6e25d6086f84147ad0 100644 (file)
@@ -1,5 +1,5 @@
 /* s12z-decode.c -- Freescale S12Z disassembly
-   Copyright (C) 2018 Free Software Foundation, Inc.
+   Copyright (C) 2018-2020 Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
 
 #include "s12z-opc.h"
 
 
-typedef int (* insn_bytes_f) (struct mem_read_abstraction_base *);
+typedef int (*insn_bytes_f) (struct mem_read_abstraction_base *);
 
-typedef void (*operands_f) (struct mem_read_abstraction_base *,
-                           int *n_operands, struct operand **operand);
+typedef int (*operands_f) (struct mem_read_abstraction_base *,
+                          int *n_operands, struct operand **operand);
 
-typedef enum operator (*discriminator_f) (struct mem_read_abstraction_base *,
-                                         enum operator hint);
+typedef enum optr (*discriminator_f) (struct mem_read_abstraction_base *,
+                                     enum optr hint);
 
 enum OPR_MODE
   {
@@ -127,15 +127,22 @@ x_opr_n_bytes (struct mem_read_abstraction_base *mra, int offset)
 static int
 opr_n_bytes_p1 (struct mem_read_abstraction_base *mra)
 {
-  return 1 + x_opr_n_bytes (mra, 0);
+  int n = x_opr_n_bytes (mra, 0);
+  if (n < 0)
+    return n;
+  return 1 + n;
 }
 
 static int
 opr_n_bytes2 (struct mem_read_abstraction_base *mra)
 {
   int s = x_opr_n_bytes (mra, 0);
-  s += x_opr_n_bytes (mra, s);
-  return s + 1;
+  if (s < 0)
+    return s;
+  int n = x_opr_n_bytes (mra, s);
+  if (n < 0)
+    return n;
+  return s + n + 1;
 }
 
 enum BB_MODE
@@ -188,7 +195,12 @@ bfextins_n_bytes (struct mem_read_abstraction_base *mra)
 
   int n = bbs->n_operands;
   if (bbs->opr)
-    n += x_opr_n_bytes (mra, n - 1);
+    {
+      int x = x_opr_n_bytes (mra, n - 1);
+      if (x < 0)
+       return x;
+      n += x;
+    }
 
   return n;
 }
@@ -256,26 +268,32 @@ xysp_reg_from_postbyte (uint8_t postbyte)
   return reg;
 }
 
-static struct operand * create_immediate_operand (int value)
+static struct operand *
+create_immediate_operand (int value)
 {
   struct immediate_operand *op = malloc (sizeof (*op));
 
-  ((struct operand *)op)->cl = OPND_CL_IMMEDIATE;
-  op->value = value;
-  ((struct operand *)op)->osize = -1;
-
+  if (op != NULL)
+    {
+      op->parent.cl = OPND_CL_IMMEDIATE;
+      op->parent.osize = -1;
+      op->value = value;
+    }
   return (struct operand *) op;
 }
 
-static struct operand * create_bitfield_operand (int width, int offset)
+static struct operand *
+create_bitfield_operand (int width, int offset)
 {
   struct bitfield_operand *op = malloc (sizeof (*op));
 
-  ((struct operand *)op)->cl = OPND_CL_BIT_FIELD;
-  op->width = width;
-  op->offset = offset;
-  ((struct operand *)op)->osize = -1;
-
+  if (op != NULL)
+    {
+      op->parent.cl = OPND_CL_BIT_FIELD;
+      op->parent.osize = -1;
+      op->width = width;
+      op->offset = offset;
+    }
   return (struct operand *) op;
 }
 
@@ -284,10 +302,12 @@ create_register_operand_with_size (int reg, short osize)
 {
   struct register_operand *op = malloc (sizeof (*op));
 
-  ((struct operand *)op)->cl = OPND_CL_REGISTER;
-  op->reg = reg;
-  ((struct operand *)op)->osize = osize;
-
+  if (op != NULL)
+    {
+      op->parent.cl = OPND_CL_REGISTER;
+      op->parent.osize = osize;
+      op->reg = reg;
+    }
   return (struct operand *) op;
 }
 
@@ -297,23 +317,29 @@ create_register_operand (int reg)
   return create_register_operand_with_size (reg, -1);
 }
 
-static struct operand * create_register_all_operand (void)
+static struct operand *
+create_register_all_operand (void)
 {
   struct register_operand *op = malloc (sizeof (*op));
 
-  ((struct operand *)op)->cl = OPND_CL_REGISTER_ALL;
-  ((struct operand *)op)->osize = -1;
-
+  if (op != NULL)
+    {
+      op->parent.cl = OPND_CL_REGISTER_ALL;
+      op->parent.osize = -1;
+    }
   return (struct operand *) op;
 }
 
-static struct operand * create_register_all16_operand (void)
+static struct operand *
+create_register_all16_operand (void)
 {
   struct register_operand *op = malloc (sizeof (*op));
 
-  ((struct operand *)op)->cl = OPND_CL_REGISTER_ALL16;
-  ((struct operand *)op)->osize = -1;
-
+  if (op != NULL)
+    {
+      op->parent.cl = OPND_CL_REGISTER_ALL16;
+      op->parent.osize = -1;
+    }
   return (struct operand *) op;
 }
 
@@ -321,16 +347,18 @@ static struct operand * create_register_all16_operand (void)
 static struct operand *
 create_simple_memory_operand (bfd_vma addr, bfd_vma base, bool relative)
 {
-  struct simple_memory_operand *op = malloc (sizeof (*op));
-
-  ((struct operand *)op)->cl = OPND_CL_SIMPLE_MEMORY;
-  op->addr = addr;
-  op->base = base;
-  op->relative = relative;
-  ((struct operand *)op)->osize = -1;
+  struct simple_memory_operand *op;
 
   assert (relative || base == 0);
-
+  op = malloc (sizeof (*op));
+  if (op != NULL)
+    {
+      op->parent.cl = OPND_CL_SIMPLE_MEMORY;
+      op->parent.osize = -1;
+      op->addr = addr;
+      op->base = base;
+      op->relative = relative;
+    }
   return (struct operand *) op;
 }
 
@@ -339,15 +367,17 @@ create_memory_operand (bool indirect, int base, int n_regs, int reg0, int reg1)
 {
   struct memory_operand *op = malloc (sizeof (*op));
 
-  ((struct operand *)op)->cl = OPND_CL_MEMORY;
-  op->indirect = indirect;
-  op->base_offset = base;
-  op->mutation = OPND_RM_NONE;
-  op->n_regs = n_regs;
-  op->regs[0] = reg0;
-  op->regs[1] = reg1;
-  ((struct operand *)op)->osize = -1;
-
+  if (op != NULL)
+    {
+      op->parent.cl = OPND_CL_MEMORY;
+      op->parent.osize = -1;
+      op->indirect = indirect;
+      op->base_offset = base;
+      op->mutation = OPND_RM_NONE;
+      op->n_regs = n_regs;
+      op->regs[0] = reg0;
+      op->regs[1] = reg1;
+    }
   return (struct operand *) op;
 }
 
@@ -356,27 +386,31 @@ create_memory_auto_operand (enum op_reg_mutation mutation, int reg)
 {
   struct memory_operand *op = malloc (sizeof (*op));
 
-  ((struct operand *)op)->cl = OPND_CL_MEMORY;
-  op->indirect = false;
-  op->base_offset = 0;
-  op->mutation = mutation;
-  op->n_regs = 1;
-  op->regs[0] = reg;
-  op->regs[1] = -1;
-  ((struct operand *)op)->osize = -1;
-
+  if (op != NULL)
+    {
+      op->parent.cl = OPND_CL_MEMORY;
+      op->parent.osize = -1;
+      op->indirect = false;
+      op->base_offset = 0;
+      op->mutation = mutation;
+      op->n_regs = 1;
+      op->regs[0] = reg;
+      op->regs[1] = -1;
+    }
   return (struct operand *) op;
 }
 
 \f
 
-static void
-z_ext24_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand)
+static int
+z_ext24_decode (struct mem_read_abstraction_base *mra, int *n_operands,
+               struct operand **operand)
 {
+  struct operand *op;
   uint8_t buffer[3];
   int status = mra->read (mra, 0, 3, buffer);
   if (status < 0)
-    return;
+    return status;
 
   int i;
   uint32_t addr = 0;
@@ -386,68 +420,77 @@ z_ext24_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct o
       addr |= buffer[i];
     }
 
-  operand[(*n_operands)++] = create_simple_memory_operand (addr, 0, false);
+  op = create_simple_memory_operand (addr, 0, false);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
 
-static uint32_t
-z_decode_signed_value (struct mem_read_abstraction_base *mra, int offset, short size)
+static int
+z_decode_signed_value (struct mem_read_abstraction_base *mra, int offset,
+                      short size, uint32_t *result)
 {
   assert (size >0);
   assert (size <= 4);
   bfd_byte buffer[4];
-  if (0 > mra->read (mra, offset, size, buffer))
-    {
-      return 0;
-    }
+  int status = mra->read (mra, offset, size, buffer);
+  if (status < 0)
+    return status;
 
   int i;
   uint32_t value = 0;
   for (i = 0; i < size; ++i)
-    {
-      value |= buffer[i] << (8 * (size - i - 1));
-    }
+    value = (value << 8) | buffer[i];
 
   if (buffer[0] & 0x80)
     {
       /* Deal with negative values */
-      value -= 0x1UL << (size * 8);
+      value -= 1u << (size * 4) << (size * 4);
     }
-  return value;
+  *result = value;
+  return 0;
 }
 
-static uint32_t
-decode_signed_value (struct mem_read_abstraction_base *mra, short size)
+static int
+decode_signed_value (struct mem_read_abstraction_base *mra, short size,
+                    uint32_t *result)
 {
-  return z_decode_signed_value (mra, 0, size);
+  return z_decode_signed_value (mra, 0, size, result);
 }
 
-static void
+static int
 x_imm1 (struct mem_read_abstraction_base *mra,
        int offset,
        int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   bfd_byte byte;
   int status = mra->read (mra, offset, 1, &byte);
   if (status < 0)
-    return;
+    return status;
 
-  operand[(*n_operands)++] = create_immediate_operand (byte);
+  op = create_immediate_operand (byte);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
 /* An eight bit immediate operand.  */
-static void
+static int
 imm1_decode (struct mem_read_abstraction_base *mra,
-       int *n_operands, struct operand **operand)
+            int *n_operands, struct operand **operand)
 {
-  x_imm1 (mra, 0, n_operands, operand);
+  return x_imm1 (mra, 0, n_operands, operand);
 }
 
-static void
+static int
 trap_decode (struct mem_read_abstraction_base *mra,
             int *n_operands, struct operand **operand)
 {
-  x_imm1 (mra, -1, n_operands, operand);
+  return x_imm1 (mra, -1, n_operands, operand);
 }
 
 
@@ -485,30 +528,30 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
        else
          n = x;
 
-        operand = create_immediate_operand (n);
+       operand = create_immediate_operand (n);
        break;
       }
     case OPR_REG:
       {
        uint8_t x = (postbyte & 0x07);
-        operand = create_register_operand (x);
+       operand = create_register_operand (x);
        break;
       }
     case OPR_OFXYS:
       {
-        operand = create_memory_operand (false, postbyte & 0x0F, 1,
+       operand = create_memory_operand (false, postbyte & 0x0F, 1,
                                         xysp_reg_from_postbyte (postbyte), -1);
        break;
       }
     case OPR_REG_DIRECT:
       {
-        operand = create_memory_operand (false, 0, 2, postbyte & 0x07,
+       operand = create_memory_operand (false, 0, 2, postbyte & 0x07,
                                         xysp_reg_from_postbyte (postbyte));
        break;
       }
     case OPR_REG_INDIRECT:
       {
-        operand = create_memory_operand (true, 0, 2, postbyte & 0x07,
+       operand = create_memory_operand (true, 0, 2, postbyte & 0x07,
                                         (postbyte & 0x10) ? REG_Y : REG_X);
        break;
       }
@@ -516,7 +559,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
     case OPR_IDX_INDIRECT:
       {
        uint8_t x1;
-       mra->read (mra, offset, 1, &x1);
+       status = mra->read (mra, offset, 1, &x1);
+       if (status < 0)
+         return NULL;
        int idx = x1;
 
        if (postbyte & 0x01)
@@ -525,7 +570,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
            idx -= 0x1UL << 8;
          }
 
-        operand = create_memory_operand (true, idx, 1,
+       operand = create_memory_operand (true, idx, 1,
                                         xysp_reg_from_postbyte (postbyte), -1);
        break;
       }
@@ -533,7 +578,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
     case OPR_IDX3_DIRECT:
       {
        uint8_t x[3];
-       mra->read (mra, offset, 3, x);
+       status = mra->read (mra, offset, 3, x);
+       if (status < 0)
+         return NULL;
        int idx = x[0] << 16 | x[1] << 8 | x[2];
 
        if (x[0] & 0x80)
@@ -542,7 +589,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
            idx -= 0x1UL << 24;
          }
 
-        operand = create_memory_operand (false, idx, 1,
+       operand = create_memory_operand (false, idx, 1,
                                         xysp_reg_from_postbyte (postbyte), -1);
        break;
       }
@@ -550,7 +597,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
     case OPR_IDX3_DIRECT_REG:
       {
        uint8_t x[3];
-       mra->read (mra, offset, 3, x);
+       status = mra->read (mra, offset, 3, x);
+       if (status < 0)
+         return NULL;
        int idx = x[0] << 16 | x[1] << 8 | x[2];
 
        if (x[0] & 0x80)
@@ -559,14 +608,16 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
            idx -= 0x1UL << 24;
          }
 
-        operand = create_memory_operand (false, idx, 1, postbyte & 0x07, -1);
+       operand = create_memory_operand (false, idx, 1, postbyte & 0x07, -1);
        break;
       }
 
     case OPR_IDX3_INDIRECT:
       {
        uint8_t x[3];
-       mra->read (mra, offset, 3, x);
+       status = mra->read (mra, offset, 3, x);
+       if (status < 0)
+         return NULL;
        int idx = x[0] << 16 | x[1] << 8 | x[2];
 
        if (x[0] & 0x80)
@@ -583,7 +634,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
     case OPR_IDX_DIRECT:
       {
        uint8_t x1;
-       mra->read (mra, offset, 1, &x1);
+       status = mra->read (mra, offset, 1, &x1);
+       if (status < 0)
+         return NULL;
        int idx = x1;
 
        if (postbyte & 0x01)
@@ -592,7 +645,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
            idx -= 0x1UL << 8;
          }
 
-        operand = create_memory_operand (false, idx, 1,
+       operand = create_memory_operand (false, idx, 1,
                                         xysp_reg_from_postbyte (postbyte), -1);
        break;
       }
@@ -600,11 +653,13 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
     case OPR_IDX2_REG:
       {
        uint8_t x[2];
-       mra->read (mra, offset, 2, x);
+       status = mra->read (mra, offset, 2, x);
+       if (status < 0)
+         return NULL;
        uint32_t idx = x[1] | x[0] << 8 ;
        idx |= (postbyte & 0x30) << 12;
 
-        operand = create_memory_operand (false, idx, 1, postbyte & 0x07, -1);
+       operand = create_memory_operand (false, idx, 1, postbyte & 0x07, -1);
        break;
       }
 
@@ -649,7 +704,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
        bfd_byte buffer[4];
        status = mra->read (mra, offset, size, buffer);
        if (status < 0)
-         operand = NULL;
+         return NULL;
 
        uint32_t ext18 = 0;
        for (i = 0; i < size; ++i)
@@ -668,7 +723,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
     case OPR_EXT1:
       {
        uint8_t x1 = 0;
-       mra->read (mra, offset, 1, &x1);
+       status = mra->read (mra, offset, 1, &x1);
+       if (status < 0)
+         return NULL;
        int16_t addr;
        addr = x1;
        addr |= (postbyte & 0x3f) << 8;
@@ -683,7 +740,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
        bfd_byte buffer[4];
        status = mra->read (mra, offset, size, buffer);
        if (status < 0)
-         operand = NULL;
+         return NULL;
 
        uint32_t ext24 = 0;
        for (i = 0; i < size; ++i)
@@ -701,7 +758,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
        bfd_byte buffer[4];
        status = mra->read (mra, offset, size, buffer);
        if (status < 0)
-         operand = NULL;
+         return NULL;
 
        uint32_t ext24 = 0;
        for (i = 0; i < size; ++i)
@@ -709,7 +766,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
            ext24 |= buffer[i] << (8 * (size - i - 1));
          }
 
-        operand = create_memory_operand (true, ext24, 0, -1, -1);
+       operand = create_memory_operand (true, ext24, 0, -1, -1);
        break;
       }
 
@@ -718,7 +775,8 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset,
       abort ();
     }
 
-  operand->osize = osize;
+  if (operand != NULL)
+    operand->osize = osize;
 
   return operand;
 }
@@ -729,124 +787,181 @@ x_opr_decode (struct mem_read_abstraction_base *mra, int offset)
   return x_opr_decode_with_size (mra, offset, -1);
 }
 
-static void
+static int
 z_opr_decode (struct mem_read_abstraction_base *mra,
              int *n_operands, struct operand **operand)
 {
-  operand[(*n_operands)++] = x_opr_decode (mra, 0);
+  struct operand *op = x_opr_decode (mra, 0);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void
+static int
 z_opr_decode2 (struct mem_read_abstraction_base *mra,
               int *n_operands, struct operand **operand)
 {
   int n = x_opr_n_bytes (mra, 0);
-
-  operand[(*n_operands)++] = x_opr_decode (mra, 0);
-  operand[(*n_operands)++] = x_opr_decode (mra, n);
+  if (n < 0)
+    return n;
+  struct operand *op = x_opr_decode (mra, 0);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = x_opr_decode (mra, n);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void
+static int
 imm1234 (struct mem_read_abstraction_base *mra, int base,
         int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   bfd_byte opcode;
   int status = mra->read (mra, -1, 1, &opcode);
   if (status < 0)
-    return;
+    return status;
 
   opcode -= base;
 
   int size = registers[opcode & 0xF].bytes;
 
-  uint32_t imm = decode_signed_value (mra, size);
+  uint32_t imm;
+  if (decode_signed_value (mra, size, &imm) < 0)
+    return -1;
 
-  operand[(*n_operands)++] = create_immediate_operand (imm);
+  op = create_immediate_operand (imm);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
 
 /* Special case of LD and CMP with register S and IMM operand */
-static void
+static int
 reg_s_imm (struct mem_read_abstraction_base *mra, int *n_operands,
           struct operand **operand)
 {
-  operand[(*n_operands)++] = create_register_operand (REG_S);
+  struct operand *op;
 
-  uint32_t imm = decode_signed_value (mra, 3);
-  operand[(*n_operands)++] = create_immediate_operand (imm);
+  op = create_register_operand (REG_S);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+
+  uint32_t imm;
+  if (decode_signed_value (mra, 3, &imm) < 0)
+    return -1;
+  op = create_immediate_operand (imm);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
 /* Special case of LD, CMP and ST with register S and OPR operand */
-static void
+static int
 reg_s_opr (struct mem_read_abstraction_base *mra, int *n_operands,
           struct operand **operand)
 {
-  operand[(*n_operands)++] = create_register_operand (REG_S);
-  operand[(*n_operands)++] = x_opr_decode (mra, 0);
+  struct operand *op;
+
+  op = create_register_operand (REG_S);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = x_opr_decode (mra, 0);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void
+static int
 z_imm1234_8base (struct mem_read_abstraction_base *mra, int *n_operands,
                 struct operand **operand)
 {
-  imm1234 (mra, 8, n_operands, operand);
+  return imm1234 (mra, 8, n_operands, operand);
 }
 
-static void
+static int
 z_imm1234_0base (struct mem_read_abstraction_base *mra, int *n_operands,
                 struct operand **operand)
 {
-  imm1234 (mra, 0, n_operands, operand);
+  return imm1234 (mra, 0, n_operands, operand);
 }
 
 
-static void
+static int
 z_tfr (struct mem_read_abstraction_base *mra, int *n_operands,
        struct operand **operand)
 {
+  struct operand *op;
   bfd_byte byte;
   int status = mra->read (mra, 0, 1, &byte);
   if (status < 0)
-    return;
+    return status;
 
-  operand[(*n_operands)++] = create_register_operand (byte >> 4);
-  operand[(*n_operands)++] = create_register_operand (byte & 0x0F);
+  op = create_register_operand (byte >> 4);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = create_register_operand (byte & 0x0F);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void
+static int
 z_reg (struct mem_read_abstraction_base *mra, int *n_operands,
        struct operand **operand)
 {
+  struct operand *op;
   bfd_byte byte;
   int status = mra->read (mra, -1, 1, &byte);
   if (status < 0)
-    return;
+    return status;
 
-  operand[(*n_operands)++] = create_register_operand (byte & 0x07);
+  op = create_register_operand (byte & 0x07);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
 
-static void
+static int
 reg_xy (struct mem_read_abstraction_base *mra,
        int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   bfd_byte byte;
   int status = mra->read (mra, -1, 1, &byte);
   if (status < 0)
-    return;
+    return status;
 
-  operand[(*n_operands)++] =
-    create_register_operand ((byte & 0x01) ? REG_Y : REG_X);
+  op = create_register_operand ((byte & 0x01) ? REG_Y : REG_X);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void
+static int
 lea_reg_xys_opr (struct mem_read_abstraction_base *mra,
                 int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   bfd_byte byte;
   int status = mra->read (mra, -1, 1, &byte);
   if (status < 0)
-    return;
+    return status;
 
   int reg_xys = -1;
   switch (byte & 0x03)
@@ -862,18 +977,26 @@ lea_reg_xys_opr (struct mem_read_abstraction_base *mra,
       break;
     }
 
-  operand[(*n_operands)++] = create_register_operand (reg_xys);
-  operand[(*n_operands)++] = x_opr_decode (mra, 0);
+  op = create_register_operand (reg_xys);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = x_opr_decode (mra, 0);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void
+static int
 lea_reg_xys (struct mem_read_abstraction_base *mra,
             int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   bfd_byte byte;
   int status = mra->read (mra, -1, 1, &byte);
   if (status < 0)
-    return;
+    return status;
 
   int reg_n = -1;
   switch (byte & 0x03)
@@ -891,23 +1014,30 @@ lea_reg_xys (struct mem_read_abstraction_base *mra,
 
   status = mra->read (mra, 0, 1, &byte);
   if (status < 0)
-    return;
+    return status;
 
-  operand[(*n_operands)++] = create_register_operand (reg_n);
-  operand[(*n_operands)++] = create_memory_operand (false, (int8_t) byte,
-                                                   1, reg_n, -1);
+  op = create_register_operand (reg_n);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = create_memory_operand (false, (int8_t) byte, 1, reg_n, -1);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
 
 /* PC Relative offsets of size 15 or 7 bits */
-static void
+static int
 rel_15_7 (struct mem_read_abstraction_base *mra, int offset,
          int *n_operands, struct operand **operands)
 {
+  struct operand *op;
   bfd_byte upper;
   int status = mra->read (mra, offset - 1, 1, &upper);
   if (status < 0)
-    return;
+    return status;
 
   bool rel_size = (upper & 0x80);
 
@@ -918,7 +1048,7 @@ rel_15_7 (struct mem_read_abstraction_base *mra, int offset,
       bfd_byte lower;
       status = mra->read (mra, offset, 1, &lower);
       if (status < 0)
-       return;
+       return status;
 
       addr <<= 8;
       addr |= lower;
@@ -938,17 +1068,20 @@ rel_15_7 (struct mem_read_abstraction_base *mra, int offset,
        addr = addr - 0x40;
     }
 
-  operands[(*n_operands)++] =
-    create_simple_memory_operand (addr, mra->posn (mra) - 1, true);
+  op = create_simple_memory_operand (addr, mra->posn (mra) - 1, true);
+  if (op == NULL)
+    return -1;
+  operands[(*n_operands)++] = op;
+  return 0;
 }
 
 
 /* PC Relative offsets of size 15 or 7 bits */
-static void
+static int
 decode_rel_15_7 (struct mem_read_abstraction_base *mra,
                 int *n_operands, struct operand **operand)
 {
-  rel_15_7 (mra, 1, n_operands, operand);
+  return rel_15_7 (mra, 1, n_operands, operand);
 }
 
 static int shift_n_bytes (struct mem_read_abstraction_base *);
@@ -958,55 +1091,90 @@ static int bm_rel_n_bytes (struct mem_read_abstraction_base *);
 static int mul_n_bytes (struct mem_read_abstraction_base *);
 static int bm_n_bytes (struct mem_read_abstraction_base *);
 
-static void psh_pul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
-static void shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
-static void mul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
-static void bm_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
-static void bm_rel_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
-static void mov_imm_opr (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
-static void loop_primitive_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands);
-static void bit_field_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands);
-static void exg_sex_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands);
+static int psh_pul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
+static int shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
+static int mul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
+static int bm_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
+static int bm_rel_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
+static int mov_imm_opr (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
+static int loop_primitive_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands);
+static int bit_field_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands);
+static int exg_sex_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands);
 
 
-static enum operator shift_discrim (struct mem_read_abstraction_base *mra, enum operator hint);
-static enum operator psh_pul_discrim (struct mem_read_abstraction_base *mra, enum operator hint);
-static enum operator mul_discrim (struct mem_read_abstraction_base *mra, enum operator hint);
-static enum operator loop_primitive_discrim (struct mem_read_abstraction_base *mra, enum operator hint);
-static enum operator bit_field_discrim (struct mem_read_abstraction_base *mra, enum operator hint);
-static enum operator exg_sex_discrim (struct mem_read_abstraction_base *mra, enum operator hint);
+static enum optr shift_discrim (struct mem_read_abstraction_base *mra, enum optr hint);
+static enum optr psh_pul_discrim (struct mem_read_abstraction_base *mra, enum optr hint);
+static enum optr mul_discrim (struct mem_read_abstraction_base *mra, enum optr hint);
+static enum optr loop_primitive_discrim (struct mem_read_abstraction_base *mra, enum optr hint);
+static enum optr bit_field_discrim (struct mem_read_abstraction_base *mra, enum optr hint);
+static enum optr exg_sex_discrim (struct mem_read_abstraction_base *mra, enum optr hint);
 
 
-static void
+static int
 cmp_xy (struct mem_read_abstraction_base *mra ATTRIBUTE_UNUSED,
        int *n_operands, struct operand **operand)
 {
-  operand[(*n_operands)++] = create_register_operand (REG_X);
-  operand[(*n_operands)++] = create_register_operand (REG_Y);
+  struct operand *op;
+
+  op = create_register_operand (REG_X);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = create_register_operand (REG_Y);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void
+static int
 sub_d6_x_y (struct mem_read_abstraction_base *mra ATTRIBUTE_UNUSED,
            int *n_operands, struct operand **operand)
 {
-  operand[(*n_operands)++] = create_register_operand (REG_D6);
-  operand[(*n_operands)++] = create_register_operand (REG_X);
-  operand[(*n_operands)++] = create_register_operand (REG_Y);
+  struct operand *op;
+
+  op = create_register_operand (REG_D6);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = create_register_operand (REG_X);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = create_register_operand (REG_Y);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void
+static int
 sub_d6_y_x (struct mem_read_abstraction_base *mra ATTRIBUTE_UNUSED,
            int *n_operands, struct operand **operand)
 {
-  operand[(*n_operands)++] = create_register_operand (REG_D6);
-  operand[(*n_operands)++] = create_register_operand (REG_Y);
-  operand[(*n_operands)++] = create_register_operand (REG_X);
+  struct operand *op;
+
+  op = create_register_operand (REG_D6);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = create_register_operand (REG_Y);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = create_register_operand (REG_X);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
-static void ld_18bit_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand);
+static int
+ld_18bit_decode (struct mem_read_abstraction_base *mra, int *n_operands,
+                struct operand **operand);
 
-static enum operator
-mul_discrim (struct mem_read_abstraction_base *mra, enum operator hint)
+static enum optr
+mul_discrim (struct mem_read_abstraction_base *mra, enum optr hint)
 {
   uint8_t mb;
   int status = mra->read (mra, 0, 1, &mb);
@@ -1042,7 +1210,7 @@ mul_discrim (struct mem_read_abstraction_base *mra, enum operator hint)
 struct opcode
 {
   /* The operation that this opcode performs.  */
-  enum operator operator;
+  enum optr operator;
 
   /* The size of this operation.  May be -1 if it is implied
      in the operands or if size is not applicable.  */
@@ -1622,19 +1790,20 @@ static const struct mb mul_table[] = {
 };
 
 
-static void
+static int
 mul_decode (struct mem_read_abstraction_base *mra,
            int *n_operands, struct operand **operand)
 {
   uint8_t mb;
+  struct operand *op;
   int status = mra->read (mra, 0, 1, &mb);
   if (status < 0)
-    return;
+    return status;
 
   uint8_t byte;
   status = mra->read (mra, -1, 1, &byte);
   if (status < 0)
-    return;
+    return status;
 
   enum MUL_MODE mode = -1;
   size_t i;
@@ -1647,37 +1816,67 @@ mul_decode (struct mem_read_abstraction_base *mra,
          break;
        }
     }
-  operand[(*n_operands)++] = create_register_operand (byte & 0x07);
+  op = create_register_operand (byte & 0x07);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
 
   switch (mode)
     {
     case MUL_REG_IMM:
       {
        int size = (mb & 0x3);
-       operand[(*n_operands)++] =
-         create_register_operand_with_size ((mb & 0x38) >> 3, size);
-       uint32_t imm = z_decode_signed_value (mra, 1, size + 1);
-       operand[(*n_operands)++] = create_immediate_operand (imm);
+       op = create_register_operand_with_size ((mb & 0x38) >> 3, size);
+       if (op == NULL)
+         return -1;
+       operand[(*n_operands)++] = op;
+
+       uint32_t imm;
+       if (z_decode_signed_value (mra, 1, size + 1, &imm) < 0)
+         return -1;
+       op = create_immediate_operand (imm);
+       if (op == NULL)
+         return -1;
+       operand[(*n_operands)++] = op;
       }
       break;
     case MUL_REG_REG:
-      operand[(*n_operands)++] = create_register_operand ((mb & 0x38) >> 3);
-      operand[(*n_operands)++] = create_register_operand (mb & 0x07);
+      op = create_register_operand ((mb & 0x38) >> 3);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
+      op = create_register_operand (mb & 0x07);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case MUL_REG_OPR:
-      operand[(*n_operands)++] = create_register_operand ((mb & 0x38) >> 3);
-      operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, mb & 0x3);
+      op = create_register_operand ((mb & 0x38) >> 3);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
+      op = x_opr_decode_with_size (mra, 1, mb & 0x3);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case MUL_OPR_OPR:
       {
        int first = x_opr_n_bytes (mra, 1);
-       operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1,
-                                                          (mb & 0x30) >> 4);
-       operand[(*n_operands)++] = x_opr_decode_with_size (mra, first + 1,
-                                                          (mb & 0x0c) >> 2);
+       if (first < 0)
+         return first;
+       op = x_opr_decode_with_size (mra, 1, (mb & 0x30) >> 4);
+       if (op == NULL)
+         return -1;
+       operand[(*n_operands)++] = op;
+       op = x_opr_decode_with_size (mra, first + 1, (mb & 0x0c) >> 2);
+       if (op == NULL)
+         return -1;
+       operand[(*n_operands)++] = op;
        break;
       }
     }
+  return 0;
 }
 
 
@@ -1685,10 +1884,11 @@ static int
 mul_n_bytes (struct mem_read_abstraction_base *mra)
 {
   int nx = 2;
+  int first, second;
   uint8_t mb;
   int status = mra->read (mra, 0, 1, &mb);
   if (status < 0)
-    return 0;
+    return status;
 
   enum MUL_MODE mode = -1;
   size_t i;
@@ -1712,15 +1912,20 @@ mul_n_bytes (struct mem_read_abstraction_base *mra)
     case MUL_REG_REG:
       break;
     case MUL_REG_OPR:
-      nx += x_opr_n_bytes (mra, 1);
+      first = x_opr_n_bytes (mra, 1);
+      if (first < 0)
+       return first;
+      nx += first;
       break;
     case MUL_OPR_OPR:
-      {
-       int first = x_opr_n_bytes (mra, nx - 1);
-       nx += first;
-       int second = x_opr_n_bytes (mra, nx - 1);
-       nx += second;
-      }
+      first = x_opr_n_bytes (mra, nx - 1);
+      if (first < 0)
+       return first;
+      nx += first;
+      second = x_opr_n_bytes (mra, nx - 1);
+      if (second < 0)
+       return second;
+      nx += second;
       break;
     }
 
@@ -1766,14 +1971,15 @@ static const  struct bm bm_table[] = {
   { 0x87, 0x84,     BM_RESERVED1},
 };
 
-static void
+static int
 bm_decode (struct mem_read_abstraction_base *mra,
           int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   uint8_t bm;
   int status = mra->read (mra, 0, 1, &bm);
   if (status < 0)
-    return;
+    return status;
 
   size_t i;
   enum BM_MODE mode = -1;
@@ -1791,28 +1997,44 @@ bm_decode (struct mem_read_abstraction_base *mra,
     {
     case BM_REG_IMM:
     case BM_RESERVED0:
-      operand[(*n_operands)++] = create_register_operand (bm & 0x07);
+      op = create_register_operand (bm & 0x07);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_OPR_B:
-      operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 0);
+      op = x_opr_decode_with_size (mra, 1, 0);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_OPR_W:
-      operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 1);
+      op = x_opr_decode_with_size (mra, 1, 1);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_OPR_L:
-      operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 3);
+      op = x_opr_decode_with_size (mra, 1, 3);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_OPR_REG:
     case BM_RESERVED1:
       {
        uint8_t xb;
-       mra->read (mra, 1, 1, &xb);
+       status = mra->read (mra, 1, 1, &xb);
+       if (status < 0)
+         return status;
        /* Don't emit a size suffix for register operands */
        if ((xb & 0xF8) != 0xB8)
-         operand[(*n_operands)++] =
-           x_opr_decode_with_size (mra, 1, (bm & 0x0c) >> 2);
+         op = x_opr_decode_with_size (mra, 1, (bm & 0x0c) >> 2);
        else
-         operand[(*n_operands)++] = x_opr_decode (mra, 1);
+         op = x_opr_decode (mra, 1);
+       if (op == NULL)
+         return -1;
+       operand[(*n_operands)++] = op;
       }
       break;
     }
@@ -1821,8 +2043,12 @@ bm_decode (struct mem_read_abstraction_base *mra,
   switch (mode)
     {
     case BM_REG_IMM:
+    case BM_RESERVED0:
       imm = (bm & 0x38) >> 3;
-      operand[(*n_operands)++] = create_immediate_operand (imm);
+      op = create_immediate_operand (imm);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_OPR_L:
       imm |= (bm & 0x03) << 3;
@@ -1832,27 +2058,32 @@ bm_decode (struct mem_read_abstraction_base *mra,
       /* fallthrough */
     case BM_OPR_B:
       imm |= (bm & 0x70) >> 4;
-      operand[(*n_operands)++] = create_immediate_operand (imm);
+      op = create_immediate_operand (imm);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_OPR_REG:
     case BM_RESERVED1:
-      operand[(*n_operands)++] = create_register_operand ((bm & 0x70) >> 4);
-      break;
-    case BM_RESERVED0:
-      assert (0);
+      op = create_register_operand ((bm & 0x70) >> 4);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     }
+  return 0;
 }
 
 
-static void
+static int
 bm_rel_decode (struct mem_read_abstraction_base *mra,
               int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   uint8_t bm;
   int status = mra->read (mra, 0, 1, &bm);
   if (status < 0)
-    return;
+    return status;
 
   size_t i;
   enum BM_MODE mode = -1;
@@ -1871,39 +2102,64 @@ bm_rel_decode (struct mem_read_abstraction_base *mra,
     {
     case BM_REG_IMM:
     case BM_RESERVED0:
-      operand[(*n_operands)++] = create_register_operand (bm & 0x07);
+      op = create_register_operand (bm & 0x07);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_OPR_B:
-      operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 0);
-      n = 1 + x_opr_n_bytes (mra, 1);
+      op = x_opr_decode_with_size (mra, 1, 0);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
+      n = x_opr_n_bytes (mra, 1);
+      if (n < 0)
+       return n;
+      n += 1;
       break;
     case BM_OPR_W:
-      operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 1);
-      n = 1 + x_opr_n_bytes (mra, 1);
+      op = x_opr_decode_with_size (mra, 1, 1);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
+      n = x_opr_n_bytes (mra, 1);
+      if (n < 0)
+       return n;
+      n += 1;
       break;
     case BM_OPR_L:
-      operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 3);
-      n = 1 + x_opr_n_bytes (mra, 1);
+      op = x_opr_decode_with_size (mra, 1, 3);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
+      n = x_opr_n_bytes (mra, 1);
+      if (n < 0)
+       return n;
+      n += 1;
       break;
     case BM_OPR_REG:
     case BM_RESERVED1:
       {
        uint8_t xb;
-       mra->read (mra, +1, 1, &xb);
+       status = mra->read (mra, +1, 1, &xb);
+       if (status < 0)
+         return status;
        /* Don't emit a size suffix for register operands */
        if ((xb & 0xF8) != 0xB8)
          {
            short os = (bm & 0x0c) >> 2;
-           operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, os);
+           op = x_opr_decode_with_size (mra, 1, os);
          }
        else
-         operand[(*n_operands)++] = x_opr_decode (mra, 1);
-
+         op = x_opr_decode (mra, 1);
+       if (op == NULL)
+         return -1;
+       operand[(*n_operands)++] = op;
       }
       break;
     }
 
-  int imm = 0;
+  int x, imm = 0;
   switch (mode)
     {
     case BM_OPR_L:
@@ -1914,24 +2170,39 @@ bm_rel_decode (struct mem_read_abstraction_base *mra,
       /* fall through */
     case BM_OPR_B:
       imm |= (bm & 0x70) >> 4;
-      operand[(*n_operands)++] = create_immediate_operand (imm);
+      op = create_immediate_operand (imm);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_RESERVED0:
       imm = (bm & 0x38) >> 3;
-      operand[(*n_operands)++] = create_immediate_operand (imm);
+      op = create_immediate_operand (imm);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_REG_IMM:
       imm = (bm & 0xF8) >> 3;
-      operand[(*n_operands)++] = create_immediate_operand (imm);
+      op = create_immediate_operand (imm);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
       break;
     case BM_OPR_REG:
     case BM_RESERVED1:
-      operand[(*n_operands)++] = create_register_operand ((bm & 0x70) >> 4);
-      n += x_opr_n_bytes (mra, 1);
+      op = create_register_operand ((bm & 0x70) >> 4);
+      if (op == NULL)
+       return -1;
+      operand[(*n_operands)++] = op;
+      x = x_opr_n_bytes (mra, 1);
+      if (x < 0)
+       return x;
+      n += x;
       break;
     }
 
-  rel_15_7 (mra, n + 1, n_operands, operand);
+  return rel_15_7 (mra, n + 1, n_operands, operand);
 }
 
 static int
@@ -1954,7 +2225,7 @@ bm_n_bytes (struct mem_read_abstraction_base *mra)
        }
     }
 
-  int n = 2;
+  int n = 0;
   switch (mode)
     {
     case BM_REG_IMM:
@@ -1964,15 +2235,15 @@ bm_n_bytes (struct mem_read_abstraction_base *mra)
     case BM_OPR_B:
     case BM_OPR_W:
     case BM_OPR_L:
-      n += x_opr_n_bytes (mra, 1);
-      break;
     case BM_OPR_REG:
     case BM_RESERVED1:
-      n += x_opr_n_bytes (mra, 1);
+      n = x_opr_n_bytes (mra, 1);
+      if (n < 0)
+       return n;
       break;
     }
 
-  return n;
+  return n + 2;
 }
 
 static int
@@ -2039,6 +2310,7 @@ static int
 shift_n_bytes (struct mem_read_abstraction_base *mra)
 {
   bfd_byte sb;
+  int opr1, opr2;
   int status = mra->read (mra, 0, 1, &sb);
   if (status != 0)
     return status;
@@ -2056,20 +2328,24 @@ shift_n_bytes (struct mem_read_abstraction_base *mra)
     {
     case SB_REG_REG_N_EFF:
       return 2;
-      break;
     case SB_REG_OPR_EFF:
     case SB_ROT:
-      return 2 + x_opr_n_bytes (mra, 1);
-      break;
+      opr1 = x_opr_n_bytes (mra, 1);
+      if (opr1 < 0)
+       return opr1;
+      return 2 + opr1;
     case SB_REG_OPR_OPR:
-      {
-       int opr1 = x_opr_n_bytes (mra, 1);
-       int opr2 = 0;
-       if ((sb & 0x30) != 0x20)
+      opr1 = x_opr_n_bytes (mra, 1);
+      if (opr1 < 0)
+       return opr1;
+      opr2 = 0;
+      if ((sb & 0x30) != 0x20)
+       {
          opr2 = x_opr_n_bytes (mra, opr1 + 1);
-       return 2 + opr1 + opr2;
-      }
-      break;
+         if (opr2 < 0)
+           return opr2;
+       }
+      return 2 + opr1 + opr2;
     default:
       return 3;
     }
@@ -2080,50 +2356,63 @@ shift_n_bytes (struct mem_read_abstraction_base *mra)
 \f
 
 static int
-
 mov_imm_opr_n_bytes (struct mem_read_abstraction_base *mra)
 {
   bfd_byte byte;
-  int status = mra->read (mra, -1, 1,  &byte);
+  int status = mra->read (mra, -1, 1, &byte);
   if (status < 0)
     return status;
 
   int size = byte - 0x0c + 1;
+  int n = x_opr_n_bytes (mra, size);
+  if (n < 0)
+    return n;
 
-  return size + x_opr_n_bytes (mra, size) + 1;
+  return size + n + 1;
 }
 
-static void
+static int
 mov_imm_opr (struct mem_read_abstraction_base *mra,
             int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   bfd_byte byte;
   int status = mra->read (mra, -1, 1, &byte);
   if (status < 0)
-    return ;
+    return status;
 
   int size = byte - 0x0c + 1;
-  uint32_t imm = decode_signed_value (mra, size);
+  uint32_t imm;
+  if (decode_signed_value (mra, size, &imm))
+    return -1;
 
-  operand[(*n_operands)++] = create_immediate_operand (imm);
-  operand[(*n_operands)++] = x_opr_decode (mra, size);
+  op = create_immediate_operand (imm);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  op = x_opr_decode (mra, size);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
 \f
 
-static void
+static int
 ld_18bit_decode (struct mem_read_abstraction_base *mra,
                 int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   size_t size = 3;
   bfd_byte buffer[3];
   int status = mra->read (mra, 0, 2, buffer + 1);
   if (status < 0)
-    return ;
+    return status;
 
   status = mra->read (mra, -1, 1, buffer);
   if (status < 0)
-    return ;
+    return status;
 
   buffer[0] = (buffer[0] & 0x30) >> 4;
 
@@ -2134,7 +2423,11 @@ ld_18bit_decode (struct mem_read_abstraction_base *mra,
       imm |= buffer[i] << (8 * (size - i - 1));
     }
 
-  operand[(*n_operands)++] = create_immediate_operand (imm);
+  op = create_immediate_operand (imm);
+  if (op == NULL)
+    return -1;
+  operand[(*n_operands)++] = op;
+  return 0;
 }
 
 \f
@@ -2166,7 +2459,9 @@ loop_prim_n_bytes (struct mem_read_abstraction_base *mra)
 {
   int mx = 0;
   uint8_t lb;
-  mra->read (mra, mx++, 1, &lb);
+  int status = mra->read (mra, mx++, 1, &lb);
+  if (status < 0)
+    return status;
 
   enum LP_MODE mode = -1;
   size_t i;
@@ -2182,11 +2477,16 @@ loop_prim_n_bytes (struct mem_read_abstraction_base *mra)
 
   if (mode == LP_OPR)
     {
-      mx += x_opr_n_bytes (mra, mx) ;
+      int n = x_opr_n_bytes (mra, mx);
+      if (n < 0)
+       return n;
+      mx += n;
     }
 
   uint8_t rb;
-  mra->read (mra, mx++, 1, &rb);
+  status = mra->read (mra, mx++, 1, &rb);
+  if (status < 0)
+    return status;
   if (rb & 0x80)
     mx++;
 
@@ -2196,65 +2496,86 @@ loop_prim_n_bytes (struct mem_read_abstraction_base *mra)
 
 \f
 
-static enum operator
-exg_sex_discrim (struct mem_read_abstraction_base *mra, enum operator hint ATTRIBUTE_UNUSED)
+static enum optr
+exg_sex_discrim (struct mem_read_abstraction_base *mra,
+                enum optr hint ATTRIBUTE_UNUSED)
 {
   uint8_t eb;
   int status = mra->read (mra, 0, 1, &eb);
+  enum optr operator = OP_INVALID;
   if (status < 0)
-    return OP_INVALID;
+    return operator;
 
   struct operand *op0 = create_register_operand ((eb & 0xf0) >> 4);
+  if (op0 == NULL)
+    return -1;
   struct operand *op1 = create_register_operand (eb & 0xf);
+  if (op1 == NULL)
+    return -1;
 
-  const struct reg *r0 = registers + ((struct register_operand *) op0)->reg;
-  const struct reg *r1 = registers + ((struct register_operand *) op1)->reg;
+  int reg0 = ((struct register_operand *) op0)->reg;
+  int reg1 = ((struct register_operand *) op1)->reg;
+  if (reg0 >= 0 && reg0 < S12Z_N_REGISTERS
+      && reg1 >= 0 && reg1 < S12Z_N_REGISTERS)
+    {
+      const struct reg *r0 = registers + reg0;
+      const struct reg *r1 = registers + reg1;
 
-  enum operator operator = (r0->bytes < r1->bytes) ? OP_sex : OP_exg;
+      operator = r0->bytes < r1->bytes ? OP_sex : OP_exg;
+    }
 
   free (op0);
   free (op1);
-  
+
   return operator;
 }
 
 
-static void
+static int
 exg_sex_decode (struct mem_read_abstraction_base *mra,
                int *n_operands, struct operand **operands)
 {
+  struct operand *op;
   uint8_t eb;
   int status = mra->read (mra, 0, 1, &eb);
   if (status < 0)
-    return;
+    return status;
 
   /* Ship out the operands.  */
-  operands[(*n_operands)++] =  create_register_operand ((eb & 0xf0) >> 4);
-  operands[(*n_operands)++] =  create_register_operand (eb & 0xf);
-}
-
-static enum operator
+  op = create_register_operand ((eb & 0xf0) >> 4);
+  if (op == NULL)
+    return -1;
+  operands[(*n_operands)++] = op;
+  op = create_register_operand (eb & 0xf);
+  if (op == NULL)
+    return -1;
+  operands[(*n_operands)++] = op;
+  return 0;
+}
+
+static enum optr
 loop_primitive_discrim (struct mem_read_abstraction_base *mra,
-                       enum operator hint ATTRIBUTE_UNUSED)
+                       enum optr hint ATTRIBUTE_UNUSED)
 {
   uint8_t lb;
   int status = mra->read (mra, 0, 1, &lb);
   if (status < 0)
     return OP_INVALID;
 
-  enum operator opbase = (lb & 0x80) ? OP_dbNE : OP_tbNE;
+  enum optr opbase = (lb & 0x80) ? OP_dbNE : OP_tbNE;
   return opbase + ((lb & 0x70) >> 4);
 }
 
-static void
+static int
 loop_primitive_decode (struct mem_read_abstraction_base *mra,
-                 int *n_operands, struct operand **operands)
+                      int *n_operands, struct operand **operands)
 {
-  int offs = 1;
+  struct operand *op;
+  int n, offs = 1;
   uint8_t lb;
   int status = mra->read (mra, 0, 1, &lb);
   if (status < 0)
-    return ;
+    return status;
 
   enum LP_MODE mode = -1;
   size_t i;
@@ -2271,30 +2592,42 @@ loop_primitive_decode (struct mem_read_abstraction_base *mra,
   switch (mode)
     {
     case LP_REG:
-      operands[(*n_operands)++] = create_register_operand (lb & 0x07);
+      op = create_register_operand (lb & 0x07);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     case LP_XY:
-      operands[(*n_operands)++] =
-       create_register_operand ((lb & 0x01) + REG_X);
+      op = create_register_operand ((lb & 0x01) + REG_X);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     case LP_OPR:
-      offs += x_opr_n_bytes (mra, 1);
-      operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, lb & 0x03);
+      n = x_opr_n_bytes (mra, 1);
+      if (n < 0)
+       return n;
+      offs += n;
+      op = x_opr_decode_with_size (mra, 1, lb & 0x03);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     }
 
-  rel_15_7 (mra, offs + 1, n_operands, operands);
+  return rel_15_7 (mra, offs + 1, n_operands, operands);
 }
 
 
-static enum operator
-shift_discrim (struct mem_read_abstraction_base *mra,  enum operator hint ATTRIBUTE_UNUSED)
+static enum optr
+shift_discrim (struct mem_read_abstraction_base *mra,
+              enum optr hint ATTRIBUTE_UNUSED)
 {
   size_t i;
   uint8_t sb;
   int status = mra->read (mra, 0, 1, &sb);
   if (status < 0)
-    return status;
+    return OP_INVALID;
 
   enum SB_DIR  dir = (sb & 0x40) ? SB_LEFT : SB_RIGHT;
   enum SB_TYPE type = (sb & 0x80) ? SB_ARITHMETIC : SB_LOGICAL;
@@ -2316,20 +2649,21 @@ shift_discrim (struct mem_read_abstraction_base *mra,  enum operator hint ATTRIB
 }
 
 
-static void
-shift_decode (struct mem_read_abstraction_base *mra,  int *n_operands, struct operand **operands)
+static int
+shift_decode (struct mem_read_abstraction_base *mra, int *n_operands,
+             struct operand **operands)
 {
+  struct operand *op;
   size_t i;
-
   uint8_t byte;
   int status = mra->read (mra, -1, 1, &byte);
   if (status < 0)
-    return ;
+    return status;
 
   uint8_t sb;
   status = mra->read (mra, 0, 1, &sb);
   if (status < 0)
-    return ;
+    return status;
 
   enum SB_MODE mode = -1;
   for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
@@ -2350,7 +2684,9 @@ shift_decode (struct mem_read_abstraction_base *mra,  int *n_operands, struct op
     case SB_OPR_N:
       {
        uint8_t xb;
-       mra->read (mra, 1, 1, &xb);
+       status = mra->read (mra, 1, 1, &xb);
+       if (status < 0)
+         return status;
        /* The size suffix is not printed if the OPR operand refers
           directly to a register, because the size is implied by the
           size of that register. */
@@ -2367,15 +2703,24 @@ shift_decode (struct mem_read_abstraction_base *mra,  int *n_operands, struct op
     {
     case SB_REG_REG_N_EFF:
     case SB_REG_REG_N:
-      operands[(*n_operands)++] = create_register_operand (byte & 0x07);
+      op = create_register_operand (byte & 0x07);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     case SB_REG_OPR_EFF:
     case SB_REG_OPR_OPR:
-      operands[(*n_operands)++] = create_register_operand (byte & 0x07);
+      op = create_register_operand (byte & 0x07);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
 
     case SB_ROT:
-      operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, osize);
+      op = x_opr_decode_with_size (mra, 1, osize);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
 
     default:
@@ -2387,12 +2732,17 @@ shift_decode (struct mem_read_abstraction_base *mra,  int *n_operands, struct op
     {
     case SB_REG_REG_N_EFF:
     case SB_REG_REG_N:
-      operands[(*n_operands)++] =
-       create_register_operand_with_size (sb & 0x07, osize);
+      op = create_register_operand_with_size (sb & 0x07, osize);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
 
     case SB_REG_OPR_OPR:
-      operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, osize);
+      op = x_opr_decode_with_size (mra, 1, osize);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
 
     default:
@@ -2404,53 +2754,74 @@ shift_decode (struct mem_read_abstraction_base *mra,  int *n_operands, struct op
     {
     case SB_REG_OPR_EFF:
     case SB_OPR_N:
-      operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, osize);
+      op = x_opr_decode_with_size (mra, 1, osize);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
 
     case SB_REG_REG_N:
       {
-        uint8_t xb;
-        mra->read (mra, 1, 1, &xb);
-
-        /* This case is slightly unusual.
-           If XB matches the binary pattern 0111XXXX, then instead of
-           interpreting this as a general OPR postbyte in the IMMe4 mode,
-           the XB byte is interpreted in s special way.  */
-        if ((xb & 0xF0) == 0x70)
-          {
-            if (byte & 0x10)
-              {
-                int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1);
-                operands[(*n_operands)++] = create_immediate_operand (shift);
-              }
-            else
-              {
-                /* This should not happen.  */
-                abort ();
-              }
-          }
-        else
-          {
-            operands[(*n_operands)++] = x_opr_decode (mra, 1);
-          }
+       uint8_t xb;
+       status = mra->read (mra, 1, 1, &xb);
+       if (status < 0)
+         return status;
+
+       /* This case is slightly unusual.
+          If XB matches the binary pattern 0111XXXX, then instead of
+          interpreting this as a general OPR postbyte in the IMMe4 mode,
+          the XB byte is interpreted in s special way.  */
+       if ((xb & 0xF0) == 0x70)
+         {
+           if (byte & 0x10)
+             {
+               int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1);
+               op = create_immediate_operand (shift);
+               if (op == NULL)
+                 return -1;
+               operands[(*n_operands)++] = op;
+             }
+           else
+             {
+               /* This should not happen.  */
+               abort ();
+             }
+         }
+       else
+         {
+           op = x_opr_decode (mra, 1);
+           if (op == NULL)
+             return -1;
+           operands[(*n_operands)++] = op;
+         }
       }
       break;
     case SB_REG_OPR_OPR:
       {
        uint8_t xb;
        int n = x_opr_n_bytes (mra, 1);
-       mra->read (mra, 1 + n, 1, &xb);
+       if (n < 0)
+         return n;
+       status = mra->read (mra, 1 + n, 1, &xb);
+       if (status < 0)
+         return status;
 
        if ((xb & 0xF0) == 0x70)
          {
            int imm = xb & 0x0F;
            imm <<= 1;
            imm |= (sb & 0x08) >> 3;
-           operands[(*n_operands)++] = create_immediate_operand (imm);
+           op = create_immediate_operand (imm);
+           if (op == NULL)
+             return -1;
+           operands[(*n_operands)++] = op;
          }
        else
          {
-           operands[(*n_operands)++] = x_opr_decode (mra, 1 + n);
+           op = x_opr_decode (mra, 1 + n);
+           if (op == NULL)
+             return -1;
+           operands[(*n_operands)++] = op;
          }
       }
       break;
@@ -2464,19 +2835,23 @@ shift_decode (struct mem_read_abstraction_base *mra,  int *n_operands, struct op
     case SB_REG_OPR_EFF:
     case SB_OPR_N:
       {
-        int imm = (sb & 0x08) ? 2 : 1;
-        operands[(*n_operands)++] = create_immediate_operand (imm);
+       int imm = (sb & 0x08) ? 2 : 1;
+       op = create_immediate_operand (imm);
+       if (op == NULL)
+         return -1;
+       operands[(*n_operands)++] = op;
       }
       break;
 
     default:
       break;
     }
+  return 0;
 }
 
-static enum operator
+static enum optr
 psh_pul_discrim (struct mem_read_abstraction_base *mra,
-                enum operator hint ATTRIBUTE_UNUSED)
+                enum optr hint ATTRIBUTE_UNUSED)
 {
   uint8_t byte;
   int status = mra->read (mra, 0, 1, &byte);
@@ -2487,49 +2862,64 @@ psh_pul_discrim (struct mem_read_abstraction_base *mra,
 }
 
 
-static void
+static int
 psh_pul_decode (struct mem_read_abstraction_base *mra,
                int *n_operands, struct operand **operand)
 {
+  struct operand *op;
   uint8_t byte;
   int status = mra->read (mra, 0, 1, &byte);
   if (status != 0)
-    return;
+    return status;
   int bit;
   if (byte & 0x40)
     {
       if ((byte & 0x3F) == 0)
-        {
-         operand[(*n_operands)++] = create_register_all16_operand ();
-        }
+       {
+         op = create_register_all16_operand ();
+         if (op == NULL)
+           return -1;
+         operand[(*n_operands)++] = op;
+       }
       else
        for (bit = 5; bit >= 0; --bit)
          {
            if (byte & (0x1 << bit))
              {
-               operand[(*n_operands)++] = create_register_operand (oprregs2[bit]);
+               op = create_register_operand (oprregs2[bit]);
+               if (op == NULL)
+                 return -1;
+               operand[(*n_operands)++] = op;
              }
          }
     }
   else
     {
       if ((byte & 0x3F) == 0)
-        {
-         operand[(*n_operands)++] = create_register_all_operand ();
-        }
+       {
+         op = create_register_all_operand ();
+         if (op == NULL)
+           return -1;
+         operand[(*n_operands)++] = op;
+       }
       else
        for (bit = 5; bit >= 0; --bit)
          {
            if (byte & (0x1 << bit))
              {
-               operand[(*n_operands)++] = create_register_operand (oprregs1[bit]);
+               op = create_register_operand (oprregs1[bit]);
+               if (op == NULL)
+                 return -1;
+               operand[(*n_operands)++] = op;
              }
          }
     }
+  return 0;
 }
 
-static enum operator
-bit_field_discrim (struct mem_read_abstraction_base *mra, enum operator hint ATTRIBUTE_UNUSED)
+static enum optr
+bit_field_discrim (struct mem_read_abstraction_base *mra,
+                  enum optr hint ATTRIBUTE_UNUSED)
 {
   int status;
   bfd_byte bb;
@@ -2537,24 +2927,25 @@ bit_field_discrim (struct mem_read_abstraction_base *mra, enum operator hint ATT
   if (status != 0)
     return OP_INVALID;
 
-  return  (bb & 0x80) ? OP_bfins : OP_bfext;
+  return (bb & 0x80) ? OP_bfins : OP_bfext;
 }
 
-static void
+static int
 bit_field_decode (struct mem_read_abstraction_base *mra,
                  int *n_operands, struct operand **operands)
 {
+  struct operand *op;
   int status;
 
   bfd_byte byte2;
   status = mra->read (mra, -1, 1, &byte2);
   if (status != 0)
-    return;
+    return status;
 
   bfd_byte bb;
   status = mra->read (mra, 0, 1, &bb);
   if (status != 0)
-    return;
+    return status;
 
   enum BB_MODE mode = -1;
   size_t i;
@@ -2563,10 +2954,10 @@ bit_field_decode (struct mem_read_abstraction_base *mra,
     {
       bbs = bb_modes + i;
       if ((bb & bbs->mask) == bbs->value)
-        {
-          mode = bbs->mode;
-          break;
-        }
+       {
+         mode = bbs->mode;
+         break;
+       }
     }
   int reg1 = byte2 & 0x07;
   /* First operand */
@@ -2576,15 +2967,22 @@ bit_field_decode (struct mem_read_abstraction_base *mra,
     case BB_REG_REG_IMM:
     case BB_REG_OPR_REG:
     case BB_REG_OPR_IMM:
-      operands[(*n_operands)++] = create_register_operand (reg1);
+      op = create_register_operand (reg1);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     case BB_OPR_REG_REG:
-      operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1,
-                                                         (bb >> 2) & 0x03);
+      op = x_opr_decode_with_size (mra, 1, (bb >> 2) & 0x03);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     case BB_OPR_REG_IMM:
-      operands[(*n_operands)++] = x_opr_decode_with_size (mra, 2,
-                                                         (bb >> 2) & 0x03);
+      op = x_opr_decode_with_size (mra, 2, (bb >> 2) & 0x03);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     }
 
@@ -2594,24 +2992,34 @@ bit_field_decode (struct mem_read_abstraction_base *mra,
     case BB_REG_REG_REG:
     case BB_REG_REG_IMM:
       {
-        int reg_src = (bb >> 2) & 0x07;
-        operands[(*n_operands)++] = create_register_operand (reg_src);
+       int reg_src = (bb >> 2) & 0x07;
+       op = create_register_operand (reg_src);
+       if (op == NULL)
+         return -1;
+       operands[(*n_operands)++] = op;
       }
       break;
     case BB_OPR_REG_REG:
     case BB_OPR_REG_IMM:
       {
-        int reg_src = (byte2 & 0x07);
-        operands[(*n_operands)++] = create_register_operand (reg_src);
+       int reg_src = (byte2 & 0x07);
+       op = create_register_operand (reg_src);
+       if (op == NULL)
+         return -1;
+       operands[(*n_operands)++] = op;
       }
       break;
     case BB_REG_OPR_REG:
-      operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1,
-                                                         (bb >> 2) & 0x03);
+      op = x_opr_decode_with_size (mra, 1, (bb >> 2) & 0x03);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     case BB_REG_OPR_IMM:
-      operands[(*n_operands)++] = x_opr_decode_with_size (mra, 2,
-                                                         (bb >> 2) & 0x03);
+      op = x_opr_decode_with_size (mra, 2, (bb >> 2) & 0x03);
+      if (op == NULL)
+       return -1;
+      operands[(*n_operands)++] = op;
       break;
     }
 
@@ -2622,24 +3030,33 @@ bit_field_decode (struct mem_read_abstraction_base *mra,
     case BB_OPR_REG_REG:
     case BB_REG_OPR_REG:
       {
-        int reg_parm = bb & 0x03;
-       operands[(*n_operands)++] = create_register_operand (reg_parm);
+       int reg_parm = bb & 0x03;
+       op = create_register_operand (reg_parm);
+       if (op == NULL)
+         return -1;
+       operands[(*n_operands)++] = op;
       }
       break;
     case BB_REG_REG_IMM:
     case BB_OPR_REG_IMM:
     case BB_REG_OPR_IMM:
       {
-        bfd_byte i1;
-        mra->read (mra, 1, 1, &i1);
-        int offset = i1 & 0x1f;
-        int width = bb & 0x03;
-        width <<= 3;
-        width |= i1 >> 5;
-        operands[(*n_operands)++] = create_bitfield_operand (width, offset);
+       bfd_byte i1;
+       status = mra->read (mra, 1, 1, &i1);
+       if (status < 0)
+         return status;
+       int offset = i1 & 0x1f;
+       int width = bb & 0x03;
+       width <<= 3;
+       width |= i1 >> 5;
+       op = create_bitfield_operand (width, offset);
+       if (op == NULL)
+         return -1;
+       operands[(*n_operands)++] = op;
       }
       break;
     }
+  return 0;
 }
 
 
@@ -2647,26 +3064,32 @@ bit_field_decode (struct mem_read_abstraction_base *mra,
    The operation to be performed is returned.
    The number of operands, will be placed in N_OPERANDS.
    The operands themselved into OPERANDS.  */
-static enum operator
+static enum optr
 decode_operation (const struct opcode *opc,
                  struct mem_read_abstraction_base *mra,
                  int *n_operands, struct operand **operands)
 {
-  enum operator op = opc->operator;
+  enum optr op = opc->operator;
   if (opc->discriminator)
-    op = opc->discriminator (mra, opc->operator);
+    {
+      op = opc->discriminator (mra, opc->operator);
+      if (op == OP_INVALID)
+       return op;
+    }
 
   if (opc->operands)
-    opc->operands (mra, n_operands, operands);
+    if (opc->operands (mra, n_operands, operands) < 0)
+      return OP_INVALID;
 
   if (opc->operands2)
-    opc->operands2 (mra, n_operands, operands);
+    if (opc->operands2 (mra, n_operands, operands) < 0)
+      return OP_INVALID;
 
   return op;
 }
 
 int
-decode_s12z (enum operator *myoperator, short *osize,
+decode_s12z (enum optr *myoperator, short *osize,
             int *n_operands, struct operand **operands,
             struct mem_read_abstraction_base *mra)
 {
@@ -2674,7 +3097,7 @@ decode_s12z (enum operator *myoperator, short *osize,
   bfd_byte byte;
 
   int status = mra->read (mra, 0, 1, &byte);
-  if (status != 0)
+  if (status < 0)
     return status;
 
   mra->advance (mra);
@@ -2686,7 +3109,9 @@ decode_s12z (enum operator *myoperator, short *osize,
       n_bytes++;
 
       bfd_byte byte2;
-      mra->read (mra, 0, 1, &byte2);
+      status = mra->read (mra, 0, 1, &byte2);
+      if (status < 0)
+       return status;
       mra->advance (mra);
       opc = page2 + byte2;
     }
@@ -2694,7 +3119,15 @@ decode_s12z (enum operator *myoperator, short *osize,
   *osize = opc->osize;
 
   /* Return the number of bytes in the instruction.  */
-  n_bytes += (opc && opc->insn_bytes) ? opc->insn_bytes (mra) : 0;
+  if (*myoperator != OP_INVALID && opc->insn_bytes)
+    {
+      int n = opc->insn_bytes (mra);
+      if (n < 0)
+       return n;
+      n_bytes += n;
+    }
+  else
+    n_bytes += 1;
 
   return n_bytes;
 }