* trad-core.c: Pass the u.u_ar0 value as the negative of the
[deliverable/binutils-gdb.git] / binutils / i960-pinsn.c
CommitLineData
2fa0b342
DHW
1/* Disassemble i80960 instructions.
2 */
3
4/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
5
6This file is part of BFD, the Binary File Diddler.
7
8BFD is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 1, or (at your option)
11any later version.
12
13BFD is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with BFD; see the file COPYING. If not, write to
20the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
2a5f387b 22/* $Id$ */
df33394f 23
2fa0b342 24#include "bfd.h"
2a5f387b 25#include "sysdep.h"
2fa0b342
DHW
26
27extern char *xmalloc();
28extern int fputs();
29
30static char *reg_names[] = {
31/* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7",
32/* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
33/* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
34/* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp",
35/* 32 */ "pc", "ac", "ip", "tc", "fp0", "fp1", "fp2", "fp3"
36};
37
38
39static FILE *stream; /* Output goes here */
40static void print_addr();
41static void ctrl();
42static void cobr();
43static void reg();
44static int mem();
45static void ea();
46static void dstop();
47static void regop();
48static void invalid();
49static int pinsn();
50static void put_abs();
51
52
53/* Print the i960 instruction at address 'memaddr' in debugged memory,
54 * on stream 's'. Returns length of the instruction, in bytes.
55 */
56int
57print_insn_i960( memaddr, buffer, s )
58 bfd_vma memaddr;
df33394f 59 uint8e_type *buffer;
2fa0b342
DHW
60 FILE *s;
61{
62 unsigned int word1, word2;
63
64 stream = s;
65 word1 =buffer [0] |( buffer[1]<< 8) | (buffer[2] << 16) | ( buffer[3] <<24);
66 word2 =buffer [4] |( buffer[5]<< 8) | (buffer[6] << 16) | ( buffer[7] <<24);
67 return pinsn( memaddr, word1, word2 );
68}
69\f
70#define IN_GDB
71
72/*****************************************************************************
73 * All code below this point should be identical with that of
74 * the disassembler in gdmp960.
75 *****************************************************************************/
76
77struct tabent {
78 char *name;
79 char numops;
80};
81
82static int
83pinsn( memaddr, word1, word2 )
84 unsigned long memaddr;
85 unsigned long word1, word2;
86{
87 int instr_len;
88
89 instr_len = 4;
90 put_abs( word1, word2 );
91
92 /* Divide instruction set into classes based on high 4 bits of opcode*/
93 switch ( (word1 >> 28) & 0xf ){
94 case 0x0:
95 case 0x1:
96 ctrl( memaddr, word1, word2 );
97 break;
98 case 0x2:
99 case 0x3:
100 cobr( memaddr, word1, word2 );
101 break;
102 case 0x5:
103 case 0x6:
104 case 0x7:
105 reg( word1 );
106 break;
107 case 0x8:
108 case 0x9:
109 case 0xa:
110 case 0xb:
111 case 0xc:
112 instr_len = mem( memaddr, word1, word2, 0 );
113 break;
114 default:
115 /* invalid instruction, print as data word */
116 invalid( word1 );
117 break;
118 }
119 return instr_len;
120}
121
122/****************************************/
123/* CTRL format */
124/****************************************/
125static void
126ctrl( memaddr, word1, word2 )
127 unsigned long memaddr;
128 unsigned long word1, word2;
129{
130 int i;
131 static struct tabent ctrl_tab[] = {
132 NULL, 0, /* 0x00 */
133 NULL, 0, /* 0x01 */
134 NULL, 0, /* 0x02 */
135 NULL, 0, /* 0x03 */
136 NULL, 0, /* 0x04 */
137 NULL, 0, /* 0x05 */
138 NULL, 0, /* 0x06 */
139 NULL, 0, /* 0x07 */
140 "b", 1, /* 0x08 */
141 "call", 1, /* 0x09 */
142 "ret", 0, /* 0x0a */
143 "bal", 1, /* 0x0b */
144 NULL, 0, /* 0x0c */
145 NULL, 0, /* 0x0d */
146 NULL, 0, /* 0x0e */
147 NULL, 0, /* 0x0f */
148 "bno", 1, /* 0x10 */
149 "bg", 1, /* 0x11 */
150 "be", 1, /* 0x12 */
151 "bge", 1, /* 0x13 */
152 "bl", 1, /* 0x14 */
153 "bne", 1, /* 0x15 */
154 "ble", 1, /* 0x16 */
155 "bo", 1, /* 0x17 */
156 "faultno", 0, /* 0x18 */
157 "faultg", 0, /* 0x19 */
158 "faulte", 0, /* 0x1a */
159 "faultge", 0, /* 0x1b */
160 "faultl", 0, /* 0x1c */
161 "faultne", 0, /* 0x1d */
162 "faultle", 0, /* 0x1e */
163 "faulto", 0, /* 0x1f */
164 };
165
166 i = (word1 >> 24) & 0xff;
167 if ( (ctrl_tab[i].name == NULL) || ((word1 & 1) != 0) ){
168 invalid( word1 );
169 return;
170 }
171
172 fputs( ctrl_tab[i].name, stream );
173 if ( word1 & 2 ){ /* Predicts branch not taken */
174 fputs( ".f", stream );
175 }
176
177 if ( ctrl_tab[i].numops == 1 ){
178 /* EXTRACT DISPLACEMENT AND CONVERT TO ADDRESS */
179 word1 &= 0x00ffffff;
180 if ( word1 & 0x00800000 ){ /* Sign bit is set */
181 word1 |= (-1 & ~0xffffff); /* Sign extend */
182 }
183 putc( '\t', stream );
184 print_addr( word1 + memaddr );
185 }
186}
187
188/****************************************/
189/* COBR format */
190/****************************************/
191static void
192cobr( memaddr, word1, word2 )
193 unsigned long memaddr;
194 unsigned long word1, word2;
195{
196 int src1;
197 int src2;
198 int i;
199
200 static struct tabent cobr_tab[] = {
201 "testno", 1, /* 0x20 */
202 "testg", 1, /* 0x21 */
203 "teste", 1, /* 0x22 */
204 "testge", 1, /* 0x23 */
205 "testl", 1, /* 0x24 */
206 "testne", 1, /* 0x25 */
207 "testle", 1, /* 0x26 */
208 "testo", 1, /* 0x27 */
209 NULL, 0, /* 0x28 */
210 NULL, 0, /* 0x29 */
211 NULL, 0, /* 0x2a */
212 NULL, 0, /* 0x2b */
213 NULL, 0, /* 0x2c */
214 NULL, 0, /* 0x2d */
215 NULL, 0, /* 0x2e */
216 NULL, 0, /* 0x2f */
217 "bbc", 3, /* 0x30 */
218 "cmpobg", 3, /* 0x31 */
219 "cmpobe", 3, /* 0x32 */
220 "cmpobge", 3, /* 0x33 */
221 "cmpobl", 3, /* 0x34 */
222 "cmpobne", 3, /* 0x35 */
223 "cmpoble", 3, /* 0x36 */
224 "bbs", 3, /* 0x37 */
225 "cmpibno", 3, /* 0x38 */
226 "cmpibg", 3, /* 0x39 */
227 "cmpibe", 3, /* 0x3a */
228 "cmpibge", 3, /* 0x3b */
229 "cmpibl", 3, /* 0x3c */
230 "cmpibne", 3, /* 0x3d */
231 "cmpible", 3, /* 0x3e */
232 "cmpibo", 3, /* 0x3f */
233 };
234
235 i = ((word1 >> 24) & 0xff) - 0x20;
236 if ( cobr_tab[i].name == NULL ){
237 invalid( word1 );
238 return;
239 }
240
241 fputs( cobr_tab[i].name, stream );
242 if ( word1 & 2 ){ /* Predicts branch not taken */
243 fputs( ".f", stream );
244 }
245 putc( '\t', stream );
246
247 src1 = (word1 >> 19) & 0x1f;
248 src2 = (word1 >> 14) & 0x1f;
249
250 if ( word1 & 0x02000 ){ /* M1 is 1 */
251 fprintf( stream, "%d", src1 );
252 } else { /* M1 is 0 */
253 fputs( reg_names[src1], stream );
254 }
255
256 if ( cobr_tab[i].numops > 1 ){
257 if ( word1 & 1 ){ /* S2 is 1 */
258 fprintf( stream, ",sf%d,", src2 );
259 } else { /* S1 is 0 */
260 fprintf( stream, ",%s,", reg_names[src2] );
261 }
262
263 /* Extract displacement and convert to address
264 */
265 word1 &= 0x00001ffc;
266 if ( word1 & 0x00001000 ){ /* Negative displacement */
267 word1 |= (-1 & ~0x1fff); /* Sign extend */
268 }
269 print_addr( memaddr + word1 );
270 }
271}
272
273/****************************************/
274/* MEM format */
275/****************************************/
276static int /* returns instruction length: 4 or 8 */
277mem( memaddr, word1, word2, noprint )
278 unsigned long memaddr;
279 unsigned long word1, word2;
280 int noprint; /* If TRUE, return instruction length, but
281 * don't output any text.
282 */
283{
284 int i, j;
285 int len;
286 int mode;
287 int offset;
288 char *reg1, *reg2, *reg3;
289
290 /* This lookup table is too sparse to make it worth typing in, but not
291 * so large as to make a sparse array necessary. We allocate the
292 * table at runtime, initialize all entries to empty, and copy the
293 * real ones in from an initialization table.
294 *
295 * NOTE: In this table, the meaning of 'numops' is:
296 * 1: single operand
297 * 2: 2 operands, load instruction
298 * -2: 2 operands, store instruction
299 */
300 static struct tabent *mem_tab = NULL;
301 static struct { int opcode; char *name; char numops; } mem_init[] = {
302#define MEM_MIN 0x80
303 0x80, "ldob", 2,
304 0x82, "stob", -2,
305 0x84, "bx", 1,
306 0x85, "balx", 2,
307 0x86, "callx", 1,
308 0x88, "ldos", 2,
309 0x8a, "stos", -2,
310 0x8c, "lda", 2,
311 0x90, "ld", 2,
312 0x92, "st", -2,
313 0x98, "ldl", 2,
314 0x9a, "stl", -2,
315 0xa0, "ldt", 2,
316 0xa2, "stt", -2,
317 0xb0, "ldq", 2,
318 0xb2, "stq", -2,
319 0xc0, "ldib", 2,
320 0xc2, "stib", -2,
321 0xc8, "ldis", 2,
322 0xca, "stis", -2,
323#define MEM_MAX 0xca
324#define MEM_SIZ ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent))
325 0, NULL, 0
326 };
327
328 if ( mem_tab == NULL ){
329 mem_tab = (struct tabent *) xmalloc( MEM_SIZ );
330 bzero( (void *) mem_tab, MEM_SIZ );
331 for ( i = 0; mem_init[i].opcode != 0; i++ ){
332 j = mem_init[i].opcode - MEM_MIN;
333 mem_tab[j].name = mem_init[i].name;
334 mem_tab[j].numops = mem_init[i].numops;
335 }
336 }
337
338 i = ((word1 >> 24) & 0xff) - MEM_MIN;
339 mode = (word1 >> 10) & 0xf;
340
341 if ( (mem_tab[i].name != NULL) /* Valid instruction */
342 && ((mode == 5) || (mode >=12)) ){ /* With 32-bit displacement */
343 len = 8;
344 } else {
345 len = 4;
346 }
347
348 if ( noprint ){
349 return len;
350 }
351
352 if ( (mem_tab[i].name == NULL) || (mode == 6) ){
353 invalid( word1 );
354 return len;
355 }
356
357 fprintf( stream, "%s\t", mem_tab[i].name );
358
359 reg1 = reg_names[ (word1 >> 19) & 0x1f ]; /* MEMB only */
360 reg2 = reg_names[ (word1 >> 14) & 0x1f ];
361 reg3 = reg_names[ word1 & 0x1f ]; /* MEMB only */
362 offset = word1 & 0xfff; /* MEMA only */
363
364 switch ( mem_tab[i].numops ){
365
366 case 2: /* LOAD INSTRUCTION */
367 if ( mode & 4 ){ /* MEMB FORMAT */
368 ea( memaddr, mode, reg2, reg3, word1, word2 );
369 fprintf( stream, ",%s", reg1 );
370 } else { /* MEMA FORMAT */
371 fprintf( stream, "0x%x", (unsigned) offset );
372 if (mode & 8) {
373 fprintf( stream, "(%s)", reg2 );
374 }
375 fprintf( stream, ",%s", reg1 );
376 }
377 break;
378
379 case -2: /* STORE INSTRUCTION */
380 if ( mode & 4 ){ /* MEMB FORMAT */
381 fprintf( stream, "%s,", reg1 );
382 ea( memaddr, mode, reg2, reg3, word1, word2 );
383 } else { /* MEMA FORMAT */
384 fprintf( stream, "%s,0x%x", reg1, (unsigned) offset );
385 if (mode & 8) {
386 fprintf( stream, "(%s)", reg2 );
387 }
388 }
389 break;
390
391 case 1: /* BX/CALLX INSTRUCTION */
392 if ( mode & 4 ){ /* MEMB FORMAT */
393 ea( memaddr, mode, reg2, reg3, word1, word2 );
394 } else { /* MEMA FORMAT */
395 fprintf( stream, "0x%x", (unsigned) offset );
396 if (mode & 8) {
397 fprintf( stream, "(%s)", reg2 );
398 }
399 }
400 break;
401 }
402
403 return len;
404}
405
406/****************************************/
407/* REG format */
408/****************************************/
409static void
410reg( word1 )
411 unsigned long word1;
412{
413 int i, j;
414 int opcode;
415 int fp;
416 int m1, m2, m3;
417 int s1, s2;
418 int src, src2, dst;
419 char *mnemp;
420
421 /* This lookup table is too sparse to make it worth typing in, but not
422 * so large as to make a sparse array necessary. We allocate the
423 * table at runtime, initialize all entries to empty, and copy the
424 * real ones in from an initialization table.
425 *
426 * NOTE: In this table, the meaning of 'numops' is:
427 * 1: single operand, which is NOT a destination.
428 * -1: single operand, which IS a destination.
429 * 2: 2 operands, the 2nd of which is NOT a destination.
430 * -2: 2 operands, the 2nd of which IS a destination.
431 * 3: 3 operands
432 *
433 * If an opcode mnemonic begins with "F", it is a floating-point
434 * opcode (the "F" is not printed).
435 */
436
437 static struct tabent *reg_tab = NULL;
438 static struct { int opcode; char *name; char numops; } reg_init[] = {
439#define REG_MIN 0x580
440 0x580, "notbit", 3,
441 0x581, "and", 3,
442 0x582, "andnot", 3,
443 0x583, "setbit", 3,
444 0x584, "notand", 3,
445 0x586, "xor", 3,
446 0x587, "or", 3,
447 0x588, "nor", 3,
448 0x589, "xnor", 3,
449 0x58a, "not", -2,
450 0x58b, "ornot", 3,
451 0x58c, "clrbit", 3,
452 0x58d, "notor", 3,
453 0x58e, "nand", 3,
454 0x58f, "alterbit", 3,
455 0x590, "addo", 3,
456 0x591, "addi", 3,
457 0x592, "subo", 3,
458 0x593, "subi", 3,
459 0x598, "shro", 3,
460 0x59a, "shrdi", 3,
461 0x59b, "shri", 3,
462 0x59c, "shlo", 3,
463 0x59d, "rotate", 3,
464 0x59e, "shli", 3,
465 0x5a0, "cmpo", 2,
466 0x5a1, "cmpi", 2,
467 0x5a2, "concmpo", 2,
468 0x5a3, "concmpi", 2,
469 0x5a4, "cmpinco", 3,
470 0x5a5, "cmpinci", 3,
471 0x5a6, "cmpdeco", 3,
472 0x5a7, "cmpdeci", 3,
473 0x5ac, "scanbyte", 2,
474 0x5ae, "chkbit", 2,
475 0x5b0, "addc", 3,
476 0x5b2, "subc", 3,
477 0x5cc, "mov", -2,
478 0x5d8, "eshro", 3,
479 0x5dc, "movl", -2,
480 0x5ec, "movt", -2,
481 0x5fc, "movq", -2,
482 0x600, "synmov", 2,
483 0x601, "synmovl", 2,
484 0x602, "synmovq", 2,
485 0x603, "cmpstr", 3,
486 0x604, "movqstr", 3,
487 0x605, "movstr", 3,
488 0x610, "atmod", 3,
489 0x612, "atadd", 3,
490 0x613, "inspacc", -2,
491 0x614, "ldphy", -2,
492 0x615, "synld", -2,
493 0x617, "fill", 3,
494 0x630, "sdma", 3,
495 0x631, "udma", 0,
496 0x640, "spanbit", -2,
497 0x641, "scanbit", -2,
498 0x642, "daddc", 3,
499 0x643, "dsubc", 3,
500 0x644, "dmovt", -2,
501 0x645, "modac", 3,
502 0x646, "condrec", -2,
503 0x650, "modify", 3,
504 0x651, "extract", 3,
505 0x654, "modtc", 3,
506 0x655, "modpc", 3,
507 0x656, "receive", -2,
508 0x659, "sysctl", 3,
509 0x660, "calls", 1,
510 0x662, "send", 3,
511 0x663, "sendserv", 1,
512 0x664, "resumprcs", 1,
513 0x665, "schedprcs", 1,
514 0x666, "saveprcs", 0,
515 0x668, "condwait", 1,
516 0x669, "wait", 1,
517 0x66a, "signal", 1,
518 0x66b, "mark", 0,
519 0x66c, "fmark", 0,
520 0x66d, "flushreg", 0,
521 0x66f, "syncf", 0,
522 0x670, "emul", 3,
523 0x671, "ediv", 3,
524 0x673, "ldtime", -1,
525 0x674, "Fcvtir", -2,
526 0x675, "Fcvtilr", -2,
527 0x676, "Fscalerl", 3,
528 0x677, "Fscaler", 3,
529 0x680, "Fatanr", 3,
530 0x681, "Flogepr", 3,
531 0x682, "Flogr", 3,
532 0x683, "Fremr", 3,
533 0x684, "Fcmpor", 2,
534 0x685, "Fcmpr", 2,
535 0x688, "Fsqrtr", -2,
536 0x689, "Fexpr", -2,
537 0x68a, "Flogbnr", -2,
538 0x68b, "Froundr", -2,
539 0x68c, "Fsinr", -2,
540 0x68d, "Fcosr", -2,
541 0x68e, "Ftanr", -2,
542 0x68f, "Fclassr", 1,
543 0x690, "Fatanrl", 3,
544 0x691, "Flogeprl", 3,
545 0x692, "Flogrl", 3,
546 0x693, "Fremrl", 3,
547 0x694, "Fcmporl", 2,
548 0x695, "Fcmprl", 2,
549 0x698, "Fsqrtrl", -2,
550 0x699, "Fexprl", -2,
551 0x69a, "Flogbnrl", -2,
552 0x69b, "Froundrl", -2,
553 0x69c, "Fsinrl", -2,
554 0x69d, "Fcosrl", -2,
555 0x69e, "Ftanrl", -2,
556 0x69f, "Fclassrl", 1,
557 0x6c0, "Fcvtri", -2,
558 0x6c1, "Fcvtril", -2,
559 0x6c2, "Fcvtzri", -2,
560 0x6c3, "Fcvtzril", -2,
561 0x6c9, "Fmovr", -2,
562 0x6d9, "Fmovrl", -2,
563 0x6e1, "Fmovre", -2,
564 0x6e2, "Fcpysre", 3,
565 0x6e3, "Fcpyrsre", 3,
566 0x701, "mulo", 3,
567 0x708, "remo", 3,
568 0x70b, "divo", 3,
569 0x741, "muli", 3,
570 0x748, "remi", 3,
571 0x749, "modi", 3,
572 0x74b, "divi", 3,
573 0x78b, "Fdivr", 3,
574 0x78c, "Fmulr", 3,
575 0x78d, "Fsubr", 3,
576 0x78f, "Faddr", 3,
577 0x79b, "Fdivrl", 3,
578 0x79c, "Fmulrl", 3,
579 0x79d, "Fsubrl", 3,
580 0x79f, "Faddrl", 3,
581#define REG_MAX 0x79f
582#define REG_SIZ ((REG_MAX-REG_MIN+1) * sizeof(struct tabent))
583 0, NULL, 0
584 };
585
586 if ( reg_tab == NULL ){
587 reg_tab = (struct tabent *) xmalloc( REG_SIZ );
588 bzero( (void *) reg_tab, REG_SIZ );
589 for ( i = 0; reg_init[i].opcode != 0; i++ ){
590 j = reg_init[i].opcode - REG_MIN;
591 reg_tab[j].name = reg_init[i].name;
592 reg_tab[j].numops = reg_init[i].numops;
593 }
594 }
595
596 opcode = ((word1 >> 20) & 0xff0) | ((word1 >> 7) & 0xf);
597 i = opcode - REG_MIN;
598
599 if ( (opcode<REG_MIN) || (opcode>REG_MAX) || (reg_tab[i].name==NULL) ){
600 invalid( word1 );
601 return;
602 }
603
604 mnemp = reg_tab[i].name;
605 if ( *mnemp == 'F' ){
606 fp = 1;
607 mnemp++;
608 } else {
609 fp = 0;
610 }
611
612 fputs( mnemp, stream );
613
614 s1 = (word1 >> 5) & 1;
615 s2 = (word1 >> 6) & 1;
616 m1 = (word1 >> 11) & 1;
617 m2 = (word1 >> 12) & 1;
618 m3 = (word1 >> 13) & 1;
619 src = word1 & 0x1f;
620 src2 = (word1 >> 14) & 0x1f;
621 dst = (word1 >> 19) & 0x1f;
622
623 if ( reg_tab[i].numops != 0 ){
624 putc( '\t', stream );
625
626 switch ( reg_tab[i].numops ){
627 case 1:
628 regop( m1, s1, src, fp );
629 break;
630 case -1:
631 dstop( m3, dst, fp );
632 break;
633 case 2:
634 regop( m1, s1, src, fp );
635 putc( ',', stream );
636 regop( m2, s2, src2, fp );
637 break;
638 case -2:
639 regop( m1, s1, src, fp );
640 putc( ',', stream );
641 dstop( m3, dst, fp );
642 break;
643 case 3:
644 regop( m1, s1, src, fp );
645 putc( ',', stream );
646 regop( m2, s2, src2, fp );
647 putc( ',', stream );
648 dstop( m3, dst, fp );
649 break;
650 }
651 }
652}
653
654
655/*
656 * Print out effective address for memb instructions.
657 */
658static void
659ea( memaddr, mode, reg2, reg3, word1, word2 )
660 unsigned long memaddr;
661 int mode;
662 char *reg2, *reg3;
663int word1;
664 unsigned int word2;
665{
666 int scale;
667 static int scale_tab[] = { 1, 2, 4, 8, 16 };
668
669 scale = (word1 >> 7) & 0x07;
670 if ( (scale > 4) || ((word1 >> 5) & 0x03 != 0) ){
671 invalid( word1 );
672 return;
673 }
674 scale = scale_tab[scale];
675
676 switch (mode) {
677 case 4: /* (reg) */
678 fprintf( stream, "(%s)", reg2 );
679 break;
680 case 5: /* displ+8(ip) */
681 print_addr( word2+8+memaddr );
682 break;
683 case 7: /* (reg)[index*scale] */
684 if (scale == 1) {
685 fprintf( stream, "(%s)[%s]", reg2, reg3 );
686 } else {
687 fprintf( stream, "(%s)[%s*%d]",reg2,reg3,scale);
688 }
689 break;
690 case 12: /* displacement */
691 print_addr( word2 );
692 break;
693 case 13: /* displ(reg) */
694 print_addr( word2 );
695 fprintf( stream, "(%s)", reg2 );
696 break;
697 case 14: /* displ[index*scale] */
698 print_addr( word2 );
699 if (scale == 1) {
700 fprintf( stream, "[%s]", reg3 );
701 } else {
702 fprintf( stream, "[%s*%d]", reg3, scale );
703 }
704 break;
705 case 15: /* displ(reg)[index*scale] */
706 print_addr( word2 );
707 if (scale == 1) {
708 fprintf( stream, "(%s)[%s]", reg2, reg3 );
709 } else {
710 fprintf( stream, "(%s)[%s*%d]",reg2,reg3,scale );
711 }
712 break;
713 default:
714 invalid( word1 );
715 return;
716 }
717}
718
719
720/************************************************/
721/* Register Instruction Operand */
722/************************************************/
723static void
724regop( mode, spec, reg, fp )
725 int mode, spec, reg, fp;
726{
727 if ( fp ){ /* FLOATING POINT INSTRUCTION */
728 if ( mode == 1 ){ /* FP operand */
729 switch ( reg ){
730 case 0: fputs( "fp0", stream ); break;
731 case 1: fputs( "fp1", stream ); break;
732 case 2: fputs( "fp2", stream ); break;
733 case 3: fputs( "fp3", stream ); break;
734 case 16: fputs( "0f0.0", stream ); break;
735 case 22: fputs( "0f1.0", stream ); break;
736 default: putc( '?', stream ); break;
737 }
738 } else { /* Non-FP register */
739 fputs( reg_names[reg], stream );
740 }
741 } else { /* NOT FLOATING POINT */
742 if ( mode == 1 ){ /* Literal */
743 fprintf( stream, "%d", reg );
744 } else { /* Register */
745 if ( spec == 0 ){
746 fputs( reg_names[reg], stream );
747 } else {
748 fprintf( stream, "sf%d", reg );
749 }
750 }
751 }
752}
753
754/************************************************/
755/* Register Instruction Destination Operand */
756/************************************************/
757static void
758dstop( mode, reg, fp )
759 int mode, reg, fp;
760{
761 /* 'dst' operand can't be a literal. On non-FP instructions, register
762 * mode is assumed and "m3" acts as if were "s3"; on FP-instructions,
763 * sf registers are not allowed so m3 acts normally.
764 */
765 if ( fp ){
766 regop( mode, 0, reg, fp );
767 } else {
768 regop( 0, mode, reg, fp );
769 }
770}
771
772
773static void
774invalid( word1 )
775 int word1;
776{
777 fprintf( stream, ".word\t0x%08x", (unsigned) word1 );
778}
779
780static void
781print_addr(a)
782int a;
783{
784 fprintf( stream, "0x%x", (unsigned) a );
785}
786
787static void
788put_abs( word1, word2 )
789 unsigned long word1, word2;
790{
791#ifdef IN_GDB
792 return;
793#else
794 int len;
795
796 switch ( (word1 >> 28) & 0xf ){
797 case 0x8:
798 case 0x9:
799 case 0xa:
800 case 0xb:
801 case 0xc:
802 /* MEM format instruction */
803 len = mem( 0, word1, word2, 1 );
804 break;
805 default:
806 len = 4;
807 break;
808 }
809
810 if ( len == 8 ){
811 fprintf( stream, "%08x %08x\t", word1, word2 );
812 } else {
813 fprintf( stream, "%08x \t", word1 );
814 }
815;
816
817#endif
818}
This page took 0.066131 seconds and 4 git commands to generate.