1/* Print instructions for the Texas TMS320C[34]X, for GDB and GNU Binutils.
2
3   Copyright 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
4
5   Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
6
7   This file is part of the GNU opcodes library.
8
9   This library is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 3, or (at your option)
12   any later version.
13
14   It is distributed in the hope that it will be useful, but WITHOUT
15   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17   License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22   MA 02110-1301, USA.  */
23
24#include <math.h>
25#include "libiberty.h"
26#include "dis-asm.h"
27#include "opcode/tic4x.h"
28
29#define TIC4X_DEBUG 0
30
31#define TIC4X_HASH_SIZE   11   /* 11 (bits) and above should give unique entries.  */
32#define TIC4X_SPESOP_SIZE 8    /* Max 8. ops for special instructions.  */
33
34typedef enum
35{
36  IMMED_SINT,
37  IMMED_SUINT,
38  IMMED_SFLOAT,
39  IMMED_INT,
40  IMMED_UINT,
41  IMMED_FLOAT
42}
43immed_t;
44
45typedef enum
46{
47  INDIRECT_SHORT,
48  INDIRECT_LONG,
49  INDIRECT_TIC4X
50}
51indirect_t;
52
53static int tic4x_version = 0;
54static int tic4x_dp = 0;
55
56static int
57tic4x_pc_offset (unsigned int op)
58{
59  /* Determine the PC offset for a C[34]x instruction.
60     This could be simplified using some boolean algebra
61     but at the expense of readability.  */
62  switch (op >> 24)
63    {
64    case 0x60:	/* br */
65    case 0x62:	/* call  (C4x) */
66    case 0x64:	/* rptb  (C4x) */
67      return 1;
68    case 0x61: 	/* brd */
69    case 0x63: 	/* laj */
70    case 0x65:	/* rptbd (C4x) */
71      return 3;
72    case 0x66: 	/* swi */
73    case 0x67:
74      return 0;
75    default:
76      break;
77    }
78
79  switch ((op & 0xffe00000) >> 20)
80    {
81    case 0x6a0:	/* bB */
82    case 0x720: /* callB */
83    case 0x740: /* trapB */
84      return 1;
85
86    case 0x6a2: /* bBd */
87    case 0x6a6: /* bBat */
88    case 0x6aa: /* bBaf */
89    case 0x722:	/* lajB */
90    case 0x748: /* latB */
91    case 0x798: /* rptbd */
92      return 3;
93
94    default:
95      break;
96    }
97
98  switch ((op & 0xfe200000) >> 20)
99    {
100    case 0x6e0:	/* dbB */
101      return 1;
102
103    case 0x6e2:	/* dbBd */
104      return 3;
105
106    default:
107      break;
108    }
109
110  return 0;
111}
112
113static int
114tic4x_print_char (struct disassemble_info * info, char ch)
115{
116  if (info != NULL)
117    (*info->fprintf_func) (info->stream, "%c", ch);
118  return 1;
119}
120
121static int
122tic4x_print_str (struct disassemble_info *info, char *str)
123{
124  if (info != NULL)
125    (*info->fprintf_func) (info->stream, "%s", str);
126  return 1;
127}
128
129static int
130tic4x_print_register (struct disassemble_info *info, unsigned long regno)
131{
132  static tic4x_register_t ** registertable = NULL;
133  unsigned int i;
134
135  if (registertable == NULL)
136    {
137      registertable = xmalloc (sizeof (tic4x_register_t *) * REG_TABLE_SIZE);
138      for (i = 0; i < tic3x_num_registers; i++)
139	registertable[tic3x_registers[i].regno] = (tic4x_register_t *) (tic3x_registers + i);
140      if (IS_CPU_TIC4X (tic4x_version))
141	{
142	  /* Add C4x additional registers, overwriting
143	     any C3x registers if necessary.  */
144	  for (i = 0; i < tic4x_num_registers; i++)
145	    registertable[tic4x_registers[i].regno] =
146	      (tic4x_register_t *)(tic4x_registers + i);
147	}
148    }
149  if ((int) regno > (IS_CPU_TIC4X (tic4x_version) ? TIC4X_REG_MAX : TIC3X_REG_MAX))
150    return 0;
151  if (info != NULL)
152    (*info->fprintf_func) (info->stream, "%s", registertable[regno]->name);
153  return 1;
154}
155
156static int
157tic4x_print_addr (struct disassemble_info *info, unsigned long addr)
158{
159  if (info != NULL)
160    (*info->print_address_func)(addr, info);
161  return 1;
162}
163
164static int
165tic4x_print_relative (struct disassemble_info *info,
166		      unsigned long pc,
167		      long offset,
168		      unsigned long opcode)
169{
170  return tic4x_print_addr (info, pc + offset + tic4x_pc_offset (opcode));
171}
172
173static int
174tic4x_print_direct (struct disassemble_info *info, unsigned long arg)
175{
176  if (info != NULL)
177    {
178      (*info->fprintf_func) (info->stream, "@");
179      tic4x_print_addr (info, arg + (tic4x_dp << 16));
180    }
181  return 1;
182}
183#if 0
184/* FIXME: make the floating point stuff not rely on host
185   floating point arithmetic.  */
186
187static void
188tic4x_print_ftoa (unsigned int val, FILE *stream, fprintf_ftype pfunc)
189{
190  int e;
191  int s;
192  int f;
193  double num = 0.0;
194
195  e = EXTRS (val, 31, 24);	/* Exponent.  */
196  if (e != -128)
197    {
198      s = EXTRU (val, 23, 23);	/* Sign bit.  */
199      f = EXTRU (val, 22, 0);	/* Mantissa.  */
200      if (s)
201	f += -2 * (1 << 23);
202      else
203	f += (1 << 23);
204      num = f / (double)(1 << 23);
205      num = ldexp (num, e);
206    }
207  (*pfunc)(stream, "%.9g", num);
208}
209#endif
210
211static int
212tic4x_print_immed (struct disassemble_info *info,
213		   immed_t type,
214		   unsigned long arg)
215{
216  int s;
217  int f;
218  int e;
219  double num = 0.0;
220
221  if (info == NULL)
222    return 1;
223  switch (type)
224    {
225    case IMMED_SINT:
226    case IMMED_INT:
227      (*info->fprintf_func) (info->stream, "%ld", (long) arg);
228      break;
229
230    case IMMED_SUINT:
231    case IMMED_UINT:
232      (*info->fprintf_func) (info->stream, "%lu", arg);
233      break;
234
235    case IMMED_SFLOAT:
236      e = EXTRS (arg, 15, 12);
237      if (e != -8)
238	{
239	  s = EXTRU (arg, 11, 11);
240	  f = EXTRU (arg, 10, 0);
241	  if (s)
242	    f += -2 * (1 << 11);
243	  else
244	    f += (1 << 11);
245	  num = f / (double)(1 << 11);
246	  num = ldexp (num, e);
247	}
248      (*info->fprintf_func) (info->stream, "%f", num);
249      break;
250    case IMMED_FLOAT:
251      e = EXTRS (arg, 31, 24);
252      if (e != -128)
253	{
254	  s = EXTRU (arg, 23, 23);
255	  f = EXTRU (arg, 22, 0);
256	  if (s)
257	    f += -2 * (1 << 23);
258	  else
259	    f += (1 << 23);
260	  num = f / (double)(1 << 23);
261	  num = ldexp (num, e);
262	}
263      (*info->fprintf_func) (info->stream, "%f", num);
264      break;
265    }
266  return 1;
267}
268
269static int
270tic4x_print_cond (struct disassemble_info *info, unsigned int cond)
271{
272  static tic4x_cond_t **condtable = NULL;
273  unsigned int i;
274
275  if (condtable == NULL)
276    {
277      condtable = xmalloc (sizeof (tic4x_cond_t *) * 32);
278      for (i = 0; i < tic4x_num_conds; i++)
279	condtable[tic4x_conds[i].cond] = (tic4x_cond_t *)(tic4x_conds + i);
280    }
281  if (cond > 31 || condtable[cond] == NULL)
282    return 0;
283  if (info != NULL)
284    (*info->fprintf_func) (info->stream, "%s", condtable[cond]->name);
285  return 1;
286}
287
288static int
289tic4x_print_indirect (struct disassemble_info *info,
290		      indirect_t type,
291		      unsigned long arg)
292{
293  unsigned int aregno;
294  unsigned int modn;
295  unsigned int disp;
296  char *a;
297
298  aregno = 0;
299  modn = 0;
300  disp = 1;
301  switch(type)
302    {
303    case INDIRECT_TIC4X:		/* *+ARn(disp) */
304      disp = EXTRU (arg, 7, 3);
305      aregno = EXTRU (arg, 2, 0) + REG_AR0;
306      modn = 0;
307      break;
308    case INDIRECT_SHORT:
309      disp = 1;
310      aregno = EXTRU (arg, 2, 0) + REG_AR0;
311      modn = EXTRU (arg, 7, 3);
312      break;
313    case INDIRECT_LONG:
314      disp = EXTRU (arg, 7, 0);
315      aregno = EXTRU (arg, 10, 8) + REG_AR0;
316      modn = EXTRU (arg, 15, 11);
317      if (modn > 7 && disp != 0)
318	return 0;
319      break;
320    default:
321        (*info->fprintf_func)(info->stream, "# internal error: Unknown indirect type %d", type);
322        return 0;
323    }
324  if (modn > TIC3X_MODN_MAX)
325    return 0;
326  a = tic4x_indirects[modn].name;
327  while (*a)
328    {
329      switch (*a)
330	{
331	case 'a':
332	  tic4x_print_register (info, aregno);
333	  break;
334	case 'd':
335	  tic4x_print_immed (info, IMMED_UINT, disp);
336	  break;
337	case 'y':
338	  tic4x_print_str (info, "ir0");
339	  break;
340	case 'z':
341	  tic4x_print_str (info, "ir1");
342	  break;
343	default:
344	  tic4x_print_char (info, *a);
345	  break;
346	}
347      a++;
348    }
349  return 1;
350}
351
352static int
353tic4x_print_op (struct disassemble_info *info,
354		unsigned long instruction,
355		tic4x_inst_t *p,
356		unsigned long pc)
357{
358  int val;
359  char *s;
360  char *parallel = NULL;
361
362  /* Print instruction name.  */
363  s = p->name;
364  while (*s && parallel == NULL)
365    {
366      switch (*s)
367	{
368	case 'B':
369	  if (! tic4x_print_cond (info, EXTRU (instruction, 20, 16)))
370	    return 0;
371	  break;
372	case 'C':
373	  if (! tic4x_print_cond (info, EXTRU (instruction, 27, 23)))
374	    return 0;
375	  break;
376	case '_':
377	  parallel = s + 1;	/* Skip past `_' in name.  */
378	  break;
379	default:
380	  tic4x_print_char (info, *s);
381	  break;
382	}
383      s++;
384    }
385
386  /* Print arguments.  */
387  s = p->args;
388  if (*s)
389    tic4x_print_char (info, ' ');
390
391  while (*s)
392    {
393      switch (*s)
394	{
395	case '*': /* Indirect 0--15.  */
396	  if (! tic4x_print_indirect (info, INDIRECT_LONG,
397				      EXTRU (instruction, 15, 0)))
398	    return 0;
399	  break;
400
401	case '#': /* Only used for ldp, ldpk.  */
402	  tic4x_print_immed (info, IMMED_UINT, EXTRU (instruction, 15, 0));
403	  break;
404
405	case '@': /* Direct 0--15.  */
406	  tic4x_print_direct (info, EXTRU (instruction, 15, 0));
407	  break;
408
409	case 'A': /* Address register 24--22.  */
410	  if (! tic4x_print_register (info, EXTRU (instruction, 24, 22) +
411				      REG_AR0))
412	    return 0;
413	  break;
414
415	case 'B': /* 24-bit unsigned int immediate br(d)/call/rptb
416		     address 0--23.  */
417	  if (IS_CPU_TIC4X (tic4x_version))
418	    tic4x_print_relative (info, pc, EXTRS (instruction, 23, 0),
419				  p->opcode);
420	  else
421	    tic4x_print_addr (info, EXTRU (instruction, 23, 0));
422	  break;
423
424	case 'C': /* Indirect (short C4x) 0--7.  */
425	  if (! IS_CPU_TIC4X (tic4x_version))
426	    return 0;
427	  if (! tic4x_print_indirect (info, INDIRECT_TIC4X,
428				      EXTRU (instruction, 7, 0)))
429	    return 0;
430	  break;
431
432	case 'D':
433	  /* Cockup if get here...  */
434	  break;
435
436	case 'E': /* Register 0--7.  */
437        case 'e':
438	  if (! tic4x_print_register (info, EXTRU (instruction, 7, 0)))
439	    return 0;
440	  break;
441
442	case 'F': /* 16-bit float immediate 0--15.  */
443	  tic4x_print_immed (info, IMMED_SFLOAT,
444			     EXTRU (instruction, 15, 0));
445	  break;
446
447        case 'i': /* Extended indirect 0--7.  */
448          if (EXTRU (instruction, 7, 5) == 7)
449            {
450              if (!tic4x_print_register (info, EXTRU (instruction, 4, 0)))
451                return 0;
452              break;
453            }
454          /* Fallthrough */
455
456	case 'I': /* Indirect (short) 0--7.  */
457	  if (! tic4x_print_indirect (info, INDIRECT_SHORT,
458				      EXTRU (instruction, 7, 0)))
459	    return 0;
460	  break;
461
462        case 'j': /* Extended indirect 8--15 */
463          if (EXTRU (instruction, 15, 13) == 7)
464            {
465              if (! tic4x_print_register (info, EXTRU (instruction, 12, 8)))
466                return 0;
467              break;
468            }
469
470	case 'J': /* Indirect (short) 8--15.  */
471	  if (! tic4x_print_indirect (info, INDIRECT_SHORT,
472				      EXTRU (instruction, 15, 8)))
473	    return 0;
474	  break;
475
476	case 'G': /* Register 8--15.  */
477        case 'g':
478	  if (! tic4x_print_register (info, EXTRU (instruction, 15, 8)))
479	    return 0;
480	  break;
481
482	case 'H': /* Register 16--18.  */
483	  if (! tic4x_print_register (info, EXTRU (instruction, 18, 16)))
484	    return 0;
485	  break;
486
487	case 'K': /* Register 19--21.  */
488	  if (! tic4x_print_register (info, EXTRU (instruction, 21, 19)))
489	    return 0;
490	  break;
491
492	case 'L': /* Register 22--24.  */
493	  if (! tic4x_print_register (info, EXTRU (instruction, 24, 22)))
494	    return 0;
495	  break;
496
497	case 'M': /* Register 22--22.  */
498	  tic4x_print_register (info, EXTRU (instruction, 22, 22) + REG_R2);
499	  break;
500
501	case 'N': /* Register 23--23.  */
502	  tic4x_print_register (info, EXTRU (instruction, 23, 23) + REG_R0);
503	  break;
504
505	case 'O': /* Indirect (short C4x) 8--15.  */
506	  if (! IS_CPU_TIC4X (tic4x_version))
507	    return 0;
508	  if (! tic4x_print_indirect (info, INDIRECT_TIC4X,
509				      EXTRU (instruction, 15, 8)))
510	    return 0;
511	  break;
512
513	case 'P': /* Displacement 0--15 (used by Bcond and BcondD).  */
514	  tic4x_print_relative (info, pc, EXTRS (instruction, 15, 0),
515				p->opcode);
516	  break;
517
518	case 'Q': /* Register 0--15.  */
519        case 'q':
520	  if (! tic4x_print_register (info, EXTRU (instruction, 15, 0)))
521	    return 0;
522	  break;
523
524	case 'R': /* Register 16--20.  */
525        case 'r':
526	  if (! tic4x_print_register (info, EXTRU (instruction, 20, 16)))
527	    return 0;
528	  break;
529
530	case 'S': /* 16-bit signed immediate 0--15.  */
531	  tic4x_print_immed (info, IMMED_SINT,
532			     EXTRS (instruction, 15, 0));
533	  break;
534
535	case 'T': /* 5-bit signed immediate 16--20  (C4x stik).  */
536	  if (! IS_CPU_TIC4X (tic4x_version))
537	    return 0;
538	  if (! tic4x_print_immed (info, IMMED_SUINT,
539				   EXTRU (instruction, 20, 16)))
540	    return 0;
541	  break;
542
543	case 'U': /* 16-bit unsigned int immediate 0--15.  */
544	  tic4x_print_immed (info, IMMED_SUINT, EXTRU (instruction, 15, 0));
545	  break;
546
547	case 'V': /* 5/9-bit unsigned vector 0--4/8.  */
548	  tic4x_print_immed (info, IMMED_SUINT,
549			     IS_CPU_TIC4X (tic4x_version) ?
550			     EXTRU (instruction, 8, 0) :
551			     EXTRU (instruction, 4, 0) & ~0x20);
552	  break;
553
554	case 'W': /* 8-bit signed immediate 0--7.  */
555	  if (! IS_CPU_TIC4X (tic4x_version))
556	    return 0;
557	  tic4x_print_immed (info, IMMED_SINT, EXTRS (instruction, 7, 0));
558	  break;
559
560	case 'X': /* Expansion register 4--0.  */
561	  val = EXTRU (instruction, 4, 0) + REG_IVTP;
562	  if (val < REG_IVTP || val > REG_TVTP)
563	    return 0;
564	  if (! tic4x_print_register (info, val))
565	    return 0;
566	  break;
567
568	case 'Y': /* Address register 16--20.  */
569	  val = EXTRU (instruction, 20, 16);
570	  if (val < REG_AR0 || val > REG_SP)
571	    return 0;
572	  if (! tic4x_print_register (info, val))
573	    return 0;
574	  break;
575
576	case 'Z': /* Expansion register 16--20.  */
577	  val = EXTRU (instruction, 20, 16) + REG_IVTP;
578	  if (val < REG_IVTP || val > REG_TVTP)
579	    return 0;
580	  if (! tic4x_print_register (info, val))
581	    return 0;
582	  break;
583
584	case '|':	/* Parallel instruction.  */
585	  tic4x_print_str (info, " || ");
586	  tic4x_print_str (info, parallel);
587	  tic4x_print_char (info, ' ');
588	  break;
589
590	case ';':
591	  tic4x_print_char (info, ',');
592	  break;
593
594	default:
595	  tic4x_print_char (info, *s);
596	  break;
597	}
598      s++;
599    }
600  return 1;
601}
602
603static void
604tic4x_hash_opcode_special (tic4x_inst_t **optable_special,
605			   const tic4x_inst_t *inst)
606{
607  int i;
608
609  for (i = 0;i < TIC4X_SPESOP_SIZE; i++)
610    if (optable_special[i] != NULL
611        && optable_special[i]->opcode == inst->opcode)
612      {
613        /* Collision (we have it already) - overwrite.  */
614        optable_special[i] = (tic4x_inst_t *) inst;
615        return;
616      }
617
618  for (i = 0; i < TIC4X_SPESOP_SIZE; i++)
619    if (optable_special[i] == NULL)
620      {
621        /* Add the new opcode.  */
622        optable_special[i] = (tic4x_inst_t *) inst;
623        return;
624      }
625
626  /* This should never occur. This happens if the number of special
627     instructions exceeds TIC4X_SPESOP_SIZE. Please increase the variable
628     of this variable */
629#if TIC4X_DEBUG
630  printf ("optable_special[] is full, please increase TIC4X_SPESOP_SIZE!\n");
631#endif
632}
633
634static void
635tic4x_hash_opcode (tic4x_inst_t **optable,
636		   tic4x_inst_t **optable_special,
637		   const tic4x_inst_t *inst,
638		   const unsigned long tic4x_oplevel)
639{
640  int j;
641  int opcode = inst->opcode >> (32 - TIC4X_HASH_SIZE);
642  int opmask = inst->opmask >> (32 - TIC4X_HASH_SIZE);
643
644  /* Use a TIC4X_HASH_SIZE bit index as a hash index.  We should
645     have unique entries so there's no point having a linked list
646     for each entry?  */
647  for (j = opcode; j < opmask; j++)
648    if ((j & opmask) == opcode
649         && inst->oplevel & tic4x_oplevel)
650      {
651#if TIC4X_DEBUG
652	/* We should only have collisions for synonyms like
653	   ldp for ldi.  */
654	if (optable[j] != NULL)
655	  printf ("Collision at index %d, %s and %s\n",
656		  j, optable[j]->name, inst->name);
657#endif
658        /* Catch those ops that collide with others already inside the
659           hash, and have a opmask greater than the one we use in the
660           hash. Store them in a special-list, that will handle full
661           32-bit INSN, not only the first 11-bit (or so). */
662        if (optable[j] != NULL
663	    && inst->opmask & ~(opmask << (32 - TIC4X_HASH_SIZE)))
664          {
665            /* Add the instruction already on the list.  */
666            tic4x_hash_opcode_special (optable_special, optable[j]);
667
668            /* Add the new instruction.  */
669            tic4x_hash_opcode_special (optable_special, inst);
670          }
671
672        optable[j] = (tic4x_inst_t *) inst;
673      }
674}
675
676/* Disassemble the instruction in 'instruction'.
677   'pc' should be the address of this instruction, it will
678   be used to print the target address if this is a relative jump or call
679   the disassembled instruction is written to 'info'.
680   The function returns the length of this instruction in words.  */
681
682static int
683tic4x_disassemble (unsigned long pc,
684		   unsigned long instruction,
685		   struct disassemble_info *info)
686{
687  static tic4x_inst_t **optable = NULL;
688  static tic4x_inst_t **optable_special = NULL;
689  tic4x_inst_t *p;
690  int i;
691  unsigned long tic4x_oplevel;
692
693  tic4x_version = info->mach;
694
695  tic4x_oplevel  = (IS_CPU_TIC4X (tic4x_version)) ? OP_C4X : 0;
696  tic4x_oplevel |= OP_C3X | OP_LPWR | OP_IDLE2 | OP_ENH;
697
698  if (optable == NULL)
699    {
700      optable = xcalloc (sizeof (tic4x_inst_t *), (1 << TIC4X_HASH_SIZE));
701
702      optable_special = xcalloc (sizeof (tic4x_inst_t *), TIC4X_SPESOP_SIZE);
703
704      /* Install opcodes in reverse order so that preferred
705	 forms overwrite synonyms.  */
706      for (i = tic4x_num_insts - 1; i >= 0; i--)
707        tic4x_hash_opcode (optable, optable_special, &tic4x_insts[i],
708			   tic4x_oplevel);
709
710      /* We now need to remove the insn that are special from the
711         "normal" optable, to make the disasm search this extra list
712         for them.  */
713      for (i = 0; i < TIC4X_SPESOP_SIZE; i++)
714        if (optable_special[i] != NULL)
715          optable[optable_special[i]->opcode >> (32 - TIC4X_HASH_SIZE)] = NULL;
716    }
717
718  /* See if we can pick up any loading of the DP register...  */
719  if ((instruction >> 16) == 0x5070 || (instruction >> 16) == 0x1f70)
720    tic4x_dp = EXTRU (instruction, 15, 0);
721
722  p = optable[instruction >> (32 - TIC4X_HASH_SIZE)];
723  if (p != NULL)
724    {
725      if (((instruction & p->opmask) == p->opcode)
726           && tic4x_print_op (NULL, instruction, p, pc))
727        tic4x_print_op (info, instruction, p, pc);
728      else
729        (*info->fprintf_func) (info->stream, "%08lx", instruction);
730    }
731  else
732    {
733      for (i = 0; i<TIC4X_SPESOP_SIZE; i++)
734        if (optable_special[i] != NULL
735            && optable_special[i]->opcode == instruction)
736          {
737            (*info->fprintf_func)(info->stream, "%s", optable_special[i]->name);
738            break;
739          }
740      if (i == TIC4X_SPESOP_SIZE)
741        (*info->fprintf_func) (info->stream, "%08lx", instruction);
742    }
743
744  /* Return size of insn in words.  */
745  return 1;
746}
747
748/* The entry point from objdump and gdb.  */
749int
750print_insn_tic4x (bfd_vma memaddr, struct disassemble_info *info)
751{
752  int status;
753  unsigned long pc;
754  unsigned long op;
755  bfd_byte buffer[4];
756
757  status = (*info->read_memory_func) (memaddr, buffer, 4, info);
758  if (status != 0)
759    {
760      (*info->memory_error_func) (status, memaddr, info);
761      return -1;
762    }
763
764  pc = memaddr;
765  op = bfd_getl32 (buffer);
766  info->bytes_per_line = 4;
767  info->bytes_per_chunk = 4;
768  info->octets_per_byte = 4;
769  info->display_endian = BFD_ENDIAN_LITTLE;
770  return tic4x_disassemble (pc, op, info) * 4;
771}
772