Commit | Line | Data |
---|---|---|
430f81c3 MK |
1 | /* |
2 | * Copyright (c) 1988 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
ca67e7b4 | 6 | * @(#)kdb_opset.c 7.4 (Berkeley) 5/21/88 |
430f81c3 | 7 | */ |
e80eadd9 SL |
8 | |
9 | #include "../kdb/defs.h" | |
10 | ||
11 | /* | |
21db0892 | 12 | * Instruction printing. |
e80eadd9 SL |
13 | */ |
14 | ||
21db0892 SL |
15 | REGLIST reglist[] = { |
16 | "p2lr", &pcb.pcb_p2lr, "p2br", (int *)&pcb.pcb_p2br, | |
17 | "p1lr", &pcb.pcb_p1lr, "p1br", (int *)&pcb.pcb_p1br, | |
18 | "p0lr", &pcb.pcb_p0lr, "p0br", (int *)&pcb.pcb_p0br, | |
19 | "ksp", &pcb.pcb_ksp, "hfs", &pcb.pcb_hfs, | |
20 | "psl", &pcb.pcb_psl, "pc", &pcb.pcb_pc, | |
21 | "ach", &pcb.pcb_ach, "acl", &pcb.pcb_acl, | |
22 | "usp", &pcb.pcb_usp, "fp", &pcb.pcb_fp, | |
23 | "r12", &pcb.pcb_r12, "r11", &pcb.pcb_r11, | |
24 | "r10", &pcb.pcb_r10, "r9", &pcb.pcb_r9, | |
25 | "r8", &pcb.pcb_r8, "r7", &pcb.pcb_r7, | |
26 | "r6", &pcb.pcb_r6, "r5", &pcb.pcb_r5, | |
27 | "r4", &pcb.pcb_r4, "r3", &pcb.pcb_r3, | |
28 | "r2", &pcb.pcb_r2, "r1", &pcb.pcb_r1, | |
29 | "r0", &pcb.pcb_r0, | |
30 | 0 | |
31 | }; | |
32 | ||
e80eadd9 SL |
33 | /* |
34 | * Argument access types | |
35 | */ | |
36 | #define ACCA (8<<3) /* address only */ | |
37 | #define ACCR (1<<3) /* read */ | |
38 | #define ACCW (2<<3) /* write */ | |
39 | #define ACCM (3<<3) /* modify */ | |
40 | #define ACCB (4<<3) /* branch displacement */ | |
41 | #define ACCI (5<<3) /* XFC code */ | |
42 | ||
43 | /* | |
44 | * Argument data types | |
45 | */ | |
46 | #define TYPB 0 /* byte */ | |
47 | #define TYPW 1 /* word */ | |
48 | #define TYPL 2 /* long */ | |
49 | #define TYPQ 3 /* quad */ | |
50 | #define TYPF 4 /* float */ | |
51 | #define TYPD 5 /* double */ | |
52 | ||
53 | struct optab { | |
54 | char *iname; | |
55 | char val; | |
56 | char nargs; | |
57 | char argtype[6]; | |
58 | }; | |
59 | ||
60 | static struct optab *ioptab[256]; /* index by opcode to optab */ | |
61 | static struct optab optab[] = { /* opcode table */ | |
62 | #define OP(a,b,c,d,e,f,g,h,i) {a,b,c,d,e,f,g,h,i} | |
63 | #include "../tahoe/kdb_instrs" | |
64 | 0}; | |
65 | static char *regname[] = { | |
66 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", | |
67 | "r8", "r9", "r10", "r11", "r12", "fp", "sp", "pc" | |
68 | }; | |
9d61b7ff | 69 | static int type, space, incp; |
e80eadd9 SL |
70 | |
71 | /* set up ioptab */ | |
72 | kdbsetup() | |
73 | { | |
74 | register struct optab *p; | |
75 | ||
76 | for (p = optab; p->iname; p++) | |
77 | ioptab[p->val&LOBYTE] = p; | |
78 | } | |
79 | ||
80 | static long | |
81 | snarf(nbytes, idsp) | |
82 | { | |
83 | register long value; | |
84 | ||
9d61b7ff | 85 | value = (u_int)chkget((off_t)inkdot(incp), idsp); |
e80eadd9 SL |
86 | incp += nbytes; |
87 | return(value>>(4-nbytes)*8); | |
88 | } | |
89 | ||
9d61b7ff | 90 | printins(idsp, ins) |
e80eadd9 SL |
91 | register long ins; |
92 | { | |
93 | short argno; /* argument index */ | |
94 | register mode; /* mode */ | |
95 | register r; /* register name */ | |
9d61b7ff | 96 | register long d; /* assembled byte, word, long or float */ |
e80eadd9 SL |
97 | register char *ap; |
98 | register struct optab *ip; | |
99 | ||
100 | type = DSYM; | |
101 | space = idsp; | |
102 | ins = byte(ins); | |
103 | if ((ip = ioptab[ins]) == (struct optab *)0) { | |
104 | printf("?%2x%8t", ins); | |
105 | dotinc = 1; | |
106 | return; | |
107 | } | |
108 | printf("%s%8t",ip->iname); | |
109 | incp = 1; | |
110 | ap = ip->argtype; | |
111 | for (argno = 0; argno < ip->nargs; argno++, ap++) { | |
112 | var[argno] = 0x80000000; | |
113 | if (argno!=0) printc(','); | |
114 | top: | |
115 | if (*ap&ACCB) | |
116 | mode = 0xAF + ((*ap&7)<<5); /* branch displacement */ | |
117 | else { | |
118 | mode = bchkget(inkdot(incp),idsp); ++incp; | |
119 | } | |
120 | r = mode&0xF; | |
121 | mode >>= 4; | |
122 | switch ((int)mode) { | |
123 | case 0: case 1: | |
124 | case 2: case 3: /* short literal */ | |
125 | printc('$'); | |
126 | d = mode<<4|r; | |
127 | goto immed; | |
128 | case 4: /* [r] */ | |
129 | printf("[%s]", regname[r]); | |
130 | goto top; | |
131 | case 5: /* r */ | |
132 | printf("%s", regname[r]); | |
133 | break; | |
134 | case 6: /* (r) */ | |
135 | printf("(%s)", regname[r]); | |
136 | break; | |
137 | case 7: /* -(r) */ | |
138 | printf("-(%s)", regname[r]); | |
139 | break; | |
140 | case 9: /* *(r)+ */ | |
141 | printc('*'); | |
142 | case 8: /* (r)+ */ | |
143 | if (r == 0xF || | |
144 | mode == 8 && (r == 8 || r == 9)) { | |
145 | printc('$'); | |
146 | d = snarf((r&03)+1, idsp); | |
147 | } else { /*it's not PC immediate or abs*/ | |
148 | printf("(%s)+", regname[r]); | |
149 | break; | |
150 | } | |
151 | immed: | |
152 | if (ins == KCALL && d >= 0 && d < 200) { | |
153 | printf("%R", d); | |
154 | break; | |
155 | } | |
156 | goto disp; | |
157 | case 0xB: /* byte displacement deferred */ | |
158 | case 0xD: /* word displacement deferred */ | |
159 | case 0xF: /* long displacement deferred */ | |
160 | printc('*'); | |
161 | case 0xA: /* byte displacement */ | |
162 | case 0xC: /* word displacement */ | |
163 | case 0xE: /* long displacement */ | |
164 | d = snarf(1<<((mode>>1&03)-1), idsp); | |
165 | if (r==0xF) { /* PC offset addressing */ | |
166 | d += dot+incp; | |
167 | psymoff(d,type,""); | |
168 | var[argno]=d; | |
169 | break; | |
170 | } | |
171 | disp: | |
172 | if (d >= 0 && d < maxoff) | |
173 | printf("%R", d); | |
174 | else | |
175 | psymoff(d,type,""); | |
176 | if (mode >= 0xA) | |
177 | printf("(%s)", regname[r]); | |
178 | var[argno] = d; | |
179 | break; | |
180 | } | |
181 | } | |
182 | if (ins == CASEL) { | |
183 | if (inkdot(incp)&01) /* align */ | |
184 | incp++; | |
185 | for (argno = 0; argno <= var[2]; ++argno) { | |
186 | printc(EOR); | |
187 | printf(" %R: ", argno+var[1]); | |
188 | d = shorten(get(inkdot(incp+argno+argno), idsp)); | |
189 | if (d&0x8000) | |
190 | d -= 0x10000; | |
191 | psymoff(inkdot(incp)+d, type, ""); | |
192 | } | |
193 | incp += var[2]+var[2]+2; | |
194 | } | |
195 | dotinc = incp; | |
196 | } |