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