1 /* Print sparc instructions for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987 Free Software Foundation, Inc.
5 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
6 WARRANTY. No author or distributor accepts responsibility to anyone
7 for the consequences of using it or for whether it serves any
8 particular purpose or works at all, unless he says so in writing.
9 Refer to the GDB General Public License for full details.
11 Everyone is granted permission to copy, modify and redistribute GDB,
12 but only under the conditions described in the GDB General Public
13 License. A copy of this license is supposed to have been given to you
14 along with GDB so you can know your rights and responsibilities. It
15 should be in a file named COPYING. Among other things, the copyright
16 notice and this notice must be preserved on all copies.
18 In other words, go ahead and share GDB, but don't try to stop
19 anyone else from sharing it farther. Help stamp out software hoarding!
27 #include "sparc-opcode.h"
29 /* sparc instructions are never longer than this many bytes. */
32 /* Print the sparc instruction at address MEMADDR in debugged memory,
33 on STREAM. Returns length of the instruction, in bytes, which
76 unsigned disp : 22; /* this should really be signed. */
116 struct call_fmt call;
117 struct sethi_fmt sethi;
118 struct branch_fmt branch;
119 struct ldst_fmt ldst;
120 struct arith_imm_fmt arith_imm;
121 struct arith_fmt arith;
123 float floatval; /* ?? */
128 Error, not_branch, bicc, bicca, ba, baa, ticc, ta,
131 static char *icc_name[] =
132 { "~", "eq", "le", "lt", "leu", "ltu", "neg", "vs",
133 "", "ne", "gt", "ge", "gtu", "geu", "pos", "vc"};
135 static char *fcc_name[] =
136 { "~fb", "fbne", "fblg", "fbul", "fbl", "fbug", "fbg", "fbu",
137 "fb", "fbe", "fbue", "fbge", "fbuge", "fble", "fbule", "fbo"};
139 static char *ccc_name[] =
140 { "~cb", "cb123", "cb12", "cb13", "cb1", "cb23", "cb2", "cb3",
141 "cb", "cb0", "cb03", "cb02", "cb023", "cb01", "cb013", "cb012"};
143 static char *arith_name[] =
144 { "add", "and", "or", "xor", "sub", "andn", "orn", "xnor",
145 "addx", 0, 0, 0, "subx", 0, 0, 0};
147 static char *xarith_name[] =
148 { "taddcc", "tsubcc", "taddcctv", "tsubcctv", "mulscc", "sll", "srl", "sra"};
150 static char *state_reg_name[] =
151 { "%y", "%psr", "%wim", "%tbr", 0, 0, 0, 0};
153 static char *ldst_i_name[] =
154 { "ld", "ldub", "lduh", "ldd", "st", "stb", "sth", "std",
155 0, "ldsb", "ldsh", 0, 0, "ldstub", 0, "swap",
156 "lda", "lduba", "lduha", "ldda", "sta", "stba", "stha", "stda",
157 0, "ldsba", "ldsha", 0, 0, "ldstuba", 0, "swapa"};
159 static char *ldst_f_name[] =
160 { "ldf", "ldfsr", 0, "lddf", "stf", "stfsr", "stdfq", "stdf"};
162 static char *ldst_c_name[] =
163 { "ldc", "ldcsr", 0, "lddc", "stc", "stcsr", "stdcq", "stdc"};
165 static int this_sethi_target = -1;
166 static int last_sethi_target = -1;
167 static int sethi_value = 0;
169 static void fprint_addr1 ();
170 static void fprint_ldst ();
171 static void fprint_f_ldst ();
172 static void fprint_c_ldst ();
173 static void fprint_fpop ();
176 print_insn (memaddr, stream)
183 read_memory (memaddr, &insn, MAXLEN);
185 this_sethi_target = -1;
186 switch (insn.op1.op1)
190 fprintf (stream, "call ");
191 print_address (memaddr + (insn.call.disp << 2), stream);
194 /* Bicc, FBfcc, CBccc, SETHI format. */
195 switch (insn.op2.op2)
198 fprintf (stream, "unimp");
202 fprintf (stream, "b%s", icc_name[insn.branch.cond]);
203 if (insn.branch.a) fprintf (stream, ",a ");
204 else fprintf (stream, " ");
205 disp22 = insn.branch.disp;
206 disp22 = ((disp22 << 10) >> 10);
207 print_address (memaddr + (disp22 << 2), stream);
211 fprintf (stream, "sethi %%hi(0x%x),%s",
212 insn.sethi.imm << 10, reg_names[insn.sethi.rd]);
213 this_sethi_target = insn.sethi.rd;
214 sethi_value = insn.sethi.imm << 12;
218 fprintf (stream, "fb%s", fcc_name[insn.branch.cond]);
219 if (insn.branch.a) fprintf (stream, ",a ");
220 else fprintf (stream, " ");
221 disp22 = insn.branch.disp;
222 disp22 = ((disp22 << 10) >> 10);
223 print_address (memaddr + (disp22 << 2), stream);
227 fprintf (stream, "cb%s", ccc_name[insn.branch.cond]);
228 if (insn.branch.a) fprintf (stream, ",a ");
229 else fprintf (stream, " ");
230 disp22 = insn.branch.disp;
231 disp22 = ((disp22 << 10) >> 10);
232 print_address (memaddr + (disp22 << 2), stream);
235 fprintf (stream, "0x%x (illegal op2 format)", insn.intval);
241 /* vaguely arithmetic insns. */
242 char *rd = reg_names[insn.arith.rd];
243 char *rs1 = reg_names[insn.arith.rs1];
245 if (insn.op3.op3 <= 28)
247 /* Arithmetic insns, with a few unimplemented. */
248 register int affect_cc = insn.op3.op3 & 16;
249 char *name = arith_name[insn.op3.op3 ^ affect_cc];
250 char *tmp = affect_cc ? "cc" : "";
254 fprintf (stream, "0x%08x (unimplemented arithmetic insn)",
257 else if (insn.arith.i)
259 fprintf (stream, "%s%s %s,0x%x,%s",
260 name, tmp, rs1, insn.arith_imm.simm, rd);
261 if (last_sethi_target == insn.arith.rd)
263 fprintf (stream, "\t! ");
264 print_address (sethi_value + insn.arith_imm.simm);
269 fprintf (stream, "%s%s %s,%s,%s",
270 name, tmp, rs1, reg_names[insn.arith.rs2], rd);
274 if (insn.op3.op3 < 32)
276 fprintf (stream, "0x%08x (unimplemented arithmetic insn)",
282 int op = insn.op3.op3 ^ 32;
286 char *name = xarith_name[op];
287 /* tagged add/sub insns and shift insns. */
290 int i = insn.arith_imm.simm;
292 /* Its a shift insn. */
295 fprintf (stream, "%s %s,0x%x,%s",
300 fprintf (stream, "%s %s,%s,%s",
301 name, rs1, reg_names[insn.arith.rs2], rd);
307 /* read/write state registers. */
308 char *sr = state_reg_name[op & 7];
310 fprintf (stream, "0x%08x (unimplemented state register insn",
313 fprintf (stream, "%s %s,%s", op & 16 ? "wr" : "rd", sr, rd);
318 /* floating point insns. */
319 int opcode = insn.arith.opf;
321 fprint_fpop (stream, insn, op & 3, opcode);
326 /* coprocessor insns. */
327 char *rs2 = reg_names[insn.arith.rs2];
328 int opcode = insn.arith.opf;
330 fprintf (stream, "cpop%d rs1=%s,rs2=%s,op=0x%x,rd=%s",
331 op & 1, rs1, rs2, opcode, rd);
340 fprint_addr1 (stream, "jumpl", insn);
343 fprint_addr1 (stream, "rett", insn);
348 sprintf (rndop_buf, "t%s", icc_name[insn.branch.cond]);
349 fprint_addr1 (stream, rndop_buf, insn);
353 fprint_addr1 (stream, "iflush", insn);
360 rndop_ptr = "restore";
364 fprintf (stream, "%s %s,0x%x,%s",
366 ((insn.arith_imm.simm << 19) >> 19), rd);
370 fprintf (stream, "%s %s,%s,%s",
371 rndop_ptr, rs1, reg_names[insn.arith.rs2], rd);
376 fprintf (stream, "0x%08x (unimplemented op3 insn)",
384 /* load and store insns. */
386 char *rd = reg_names[insn.arith.rd];
387 char *rs1 = reg_names[insn.arith.rs1];
388 int op = insn.arith.op3;
393 fprint_ldst (stream, insn, op);
402 fprint_f_ldst (stream, insn, op);
405 fprintf (stream, "0x%08x (unimplemented float load/store insn)",
410 /* Coprocessor ops. */
414 fprint_c_ldst (stream, insn, op);
417 fprintf (stream, "0x%08x (unimplemented coprocessor load/store insn)",
426 /* It would be nice if this routine could print out a symbolic address
429 fprint_addr1 (stream, name, insn)
434 char *rs1 = reg_names[insn.arith.rs1];
435 char *rd = reg_names[insn.arith.rd];
439 fprintf (stream, "%s %s,0x%x,%s",
440 name, rs1, insn.arith_imm.simm, rd);
444 fprintf (stream, "%s %s,%s,%s",
445 name, rs1, reg_names[insn.arith.rs2], rd);
450 fprint_mem (stream, insn)
454 char *reg_name = reg_names[insn.arith.rs1];
457 if (insn.arith_imm.simm == 0)
458 fprintf (stream, "[%s]", reg_name);
459 else if (insn.arith_imm.simm & 0x1000)
460 fprintf (stream, "[%s-0x%x]", reg_name,
461 - (insn.arith_imm.simm | 0xffffe000));
463 fprintf (stream, "[%s+0x%x]", reg_name, insn.arith_imm.simm);
467 if (insn.arith.rs2 == 0)
468 fprintf (stream, "[%s]", reg_name);
470 fprintf (stream, "[%s,%s]", reg_names[insn.arith.rs2], reg_name);
475 fprint_ldst (stream, insn, op)
480 char *name = ldst_i_name[op];
481 char *rd = reg_names[insn.arith.rd];
487 fprintf (stream, "%s %s,", name, rd);
488 fprint_mem (stream, insn);
492 fprintf (stream, "%s ", name);
493 fprint_mem (stream, insn);
494 fprintf (stream, ",%s", rd);
498 fprintf (stream, "0x%08x (unimplemented load/store insn)", insn.intval);
502 fprint_f_ldst (stream, insn, op)
507 char *name = ldst_f_name[op];
510 char *rd = reg_names[insn.arith.rd + 32];
514 fprintf (stream, "%s %s,", name, rd);
515 fprint_mem (stream, insn);
519 fprintf (stream, "%s ", name);
520 fprint_mem (stream, insn);
521 fprintf (stream, ",%s", rd);
525 fprintf (stream, "0x%08x (unimplemented float load/store insn)", insn.intval);
529 fprint_c_ldst (stream, insn, op)
534 char *name = ldst_c_name[op];
539 fprintf (stream, "%s %%cpreg(%d),", name, insn.arith.rs1);
540 fprint_mem (stream, insn);
544 fprintf (stream, "%s ");
545 fprint_mem (stream, insn);
546 fprintf (stream, ",%%cpreg(%d)", insn.arith.rd);
550 fprintf (stream, "0x%08x (unimplemented coprocessor load/store insn)",
555 fprint_fpop (stream, insn, op, opcode)
561 char *rs1, *rs2, *rd;
566 rs2 = reg_names[insn.arith.rs2 + 32];
567 rd = reg_names[insn.arith.rd + 32];
568 if ((opcode ^ 0x2f) <= 0x2f)
591 fprintf (stream, "%s %s,%s", name, rs2, rd);
594 if ((opcode ^ 0x5f) <= 0x5f)
596 rs1 = reg_names[insn.arith.rs1 + 32];
638 if ((opcode & 0x10) == 0)
639 fprintf (stream, "%s %s,%s,%s", name, rs1, rs2, rd);
641 fprintf (stream, "%s %s,%s", name, rs1, rs2);
644 if ((opcode ^ 0xdf) <= 0xdf)
687 fprintf (stream, "%s %s,%s", name, rs2, rd);
693 rs1 = reg_names[insn.arith.rs1 + 32];
694 rs2 = reg_names[insn.arith.rs2 + 32];
695 if ((opcode ^ 0x57) <= 0x57)
720 fprintf (stream, "%s %s,%s", name, rs1, rs2);
723 else goto unimplemented;
730 fprintf (stream, "0x%08x (unimplemented fpop insn)", insn.intval);
733 /* Set *target if we find a branch */
735 isabranch (addr, target)
736 CORE_ADDR addr, *target;
738 union insn_fmt instr;
739 branch_type val = not_branch;
740 long offset; /* Must be signed for sign-extend */
743 instr.intval = read_memory_integer (addr, 4);
744 /* printf("intval = %x\n",instr.intval); */
745 switch (instr.op1.op1)
747 case 0: /* Format 2 */
748 switch(instr.op2.op2)
750 case 2: case 6: /* BICC & FBCC */
751 if (instr.branch.cond == 8)
752 val = instr.branch.a ? baa : ba;
754 val = instr.branch.a ? bicca : bicc;
755 /* 22 bits, sign extended */
756 offset = ((instr.branch.disp << 10) >> 10);
757 *target = addr + offset;
762 /*printf("isabranch ret: %d\n",val); */
766 CORE_ADDR skip_prologue (pc)
771 struct insn_fmt insn;
776 x.i = read_memory_integer (pc, 4);
777 if (x.insn.sethi.op == 0 && x.insn.sethi.op2 == 4)
779 dest = x.insn.sethi.rd;
781 x.i = read_memory_integer (pc, 4);
783 if (x.insn.arith_imm.op == 2 && x.insn.arith_imm.i == 1
784 && (x.insn.arith_imm.rd == 1 || x.insn.arith_imm.rd == dest))
787 x.i = read_memory_integer (pc, 4);
789 if (x.insn.arith.op == 2 && (x.insn.arith.op3 ^ 32) == 28)
797 frame_saved_pc (frame, next_frame)
799 CORE_ADDR next_frame;
804 prev_pc = GET_RWINDOW_REG (next_frame, rw_in[7]);
806 prev_pc = GET_RWINDOW_REG (read_register (SP_REGNUM), rw_in[7]);
808 error ("frame_saved_pc called without a frame");
810 return PC_ADJUST (prev_pc);