xref: /plan9-contrib/sys/src/cmd/db/regs.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 /*
2  * code to keep track of registers
3  */
4 
5 #include "defs.h"
6 #include "fns.h"
7 
8 /*
9  * translate a name to a magic register offset
10  */
11 Reglist*
12 rname(char *name)
13 {
14 	Reglist *rp;
15 
16 	for (rp = mach->reglist; rp->rname; rp++)
17 		if (strcmp(name, rp->rname) == 0)
18 			return rp;
19 	return 0;
20 }
21 
22 static ulong
23 getreg(Map *map, Reglist *rp)
24 {
25 
26 	long l;
27 	int ret;
28 
29 	l = 0;
30 	ret = 0;
31 	switch (rp->rformat)
32 	{
33 	case 'x':
34 		ret = get2(map, rp->raddr, (ushort*) &l);
35 		break;
36 	case 'X':
37 	case 'f':
38 	case 'F':
39 		ret = get4(map, rp->raddr, &l);
40 		break;
41 	default:
42 		werrstr("can't retrieve register %s", rp->rname);
43 		error("%r");
44 	}
45 	if (ret < 0) {
46 		werrstr("Register %s: %r", rp->rname);
47 		error("%r");
48 	}
49 	l += rp->rdelta;
50 	return l;
51 }
52 
53 ulong
54 rget(Map *map, char *name)
55 {
56 	Reglist *rp;
57 
58 	rp = rname(name);
59 	if (!rp)
60 		error("invalid register name");
61 	return getreg(map, rp);
62 }
63 
64 void
65 rput(Map *map, char *name, ulong v)
66 {
67 	Reglist *rp;
68 	int ret;
69 
70 	rp = rname(name);
71 	if (!rp)
72 		error("invalid register name");
73 	if (rp->rflags & RRDONLY)
74 		error("register is read-only");
75 	switch (rp->rformat)
76 	{
77 	case 'x':
78 		ret = put2(map, rp->raddr, (ushort) v);
79 		break;
80 	case 'X':
81 	case 'f':
82 	case 'F':
83 		ret = put4(map, rp->raddr, (long) v);
84 		break;
85 	default:
86 		ret = -1;
87 	}
88 	if (ret < 0)
89 		error("can't write register");
90 }
91 
92 void
93 fixregs(Map *map)
94 {
95 	Reglist *rp;
96 	long val;
97 
98 	if (machdata->ufixup) {
99 		if (machdata->ufixup(map, &val) < 0)
100 			error("can't fixup register addresses: %r");
101 	} else
102 		val = 0;
103 	for (rp = mach->reglist; rp->rname; rp++)
104 		rp->raddr = mach->kbase+rp->roffs-val;
105 }
106 
107 void
108 adjustreg(char *name, ulong raddr, long rdelta)
109 {
110 	Reglist *rp;
111 
112 	rp = rname(name);
113 	if (!rp)
114 		error("invalid register name");
115 	rp->raddr=raddr;
116 	rp->rdelta=rdelta;
117 }
118 
119 /*
120  * print the registers
121  */
122 void
123 printregs(int c)
124 {
125 	Reglist *rp;
126 	int i;
127 
128 	for (i = 1, rp = mach->reglist; rp->rname; rp++, i++) {
129 		if ((rp->rflags & RFLT)) {
130 			if (c != 'R')
131 				continue;
132 			if (rp->rformat == '8' || rp->rformat == '3')
133 				continue;
134 		}
135 		dprint("%-8s %-12lux", rp->rname, getreg(cormap, rp));
136 		if ((i % 3) == 0) {
137 			dprint("\n");
138 			i = 0;
139 		}
140 	}
141 	if (i != 1)
142 		dprint("\n");
143 	printsyscall();
144 	dprint ("%s\n", machdata->excep(cormap, rget));
145 	printpc();
146 }
147