changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/7l/list.c

changeset 7144: d0b9ab522e8b
author: cinap_lenrek@felloff.net
date: Mon, 08 Apr 2019 14:05:27 +0200
permissions: -rw-r--r--
description: 7l: add arm64 linker (initial sync)
1 #include "l.h"
2 
3 void
4 listinit(void)
5 {
6 
7  fmtinstall('A', Aconv);
8  fmtinstall('D', Dconv);
9  fmtinstall('P', Pconv);
10  fmtinstall('S', Sconv);
11  fmtinstall('N', Nconv);
12  fmtinstall('R', Rconv);
13 }
14 
15 int
16 Pconv(Fmt *fp)
17 {
18  char str[STRINGSZ], *s;
19  Prog *p;
20  int a;
21 
22  p = va_arg(fp->args, Prog*);
23  curp = p;
24  a = p->as;
25  switch(a) {
26  default:
27  s = str;
28  s += sprint(s, "(%ld)", p->line);
29  if(p->reg == NREG && p->from3.type == D_NONE)
30  sprint(s, " %A %D,%D",
31  a, &p->from, &p->to);
32  else if(p->from.type != D_FREG){
33  s += sprint(s, " %A %D", a, &p->from);
34  if(p->from3.type != D_NONE)
35  s += sprint(s, ",%D", &p->from3);
36  if(p->reg != NREG)
37  s += sprint(s, ",R%d", p->reg);
38  sprint(s, ",%D", &p->to);
39  }else
40  sprint(s, " %A %D,F%d,%D",
41  a, &p->from, p->reg, &p->to);
42  break;
43 
44  case ADATA:
45  case AINIT:
46  case ADYNT:
47  sprint(str, "(%ld) %A %D/%d,%D",
48  p->line, a, &p->from, p->reg, &p->to);
49  break;
50  }
51  return fmtstrcpy(fp, str);
52 }
53 
54 int
55 Aconv(Fmt *fp)
56 {
57  char *s;
58  int a;
59 
60  a = va_arg(fp->args, int);
61  s = "???";
62  if(a >= AXXX && a < ALAST && anames[a])
63  s = anames[a];
64  return fmtstrcpy(fp, s);
65 }
66 
67 char* strcond[16] =
68 {
69  "EQ",
70  "NE",
71  "HS",
72  "LO",
73  "MI",
74  "PL",
75  "VS",
76  "VC",
77  "HI",
78  "LS",
79  "GE",
80  "LT",
81  "GT",
82  "LE",
83  "AL",
84  "NV"
85 };
86 
87 int
88 Dconv(Fmt *fp)
89 {
90  char str[STRINGSZ];
91  char *op;
92  Adr *a;
93  long v;
94  static char *extop[] = {".UB", ".UH", ".UW", ".UX", ".SB", ".SH", ".SW", ".SX"};
95 
96  a = va_arg(fp->args, Adr*);
97  switch(a->type) {
98 
99  default:
100  sprint(str, "GOK-type(%d)", a->type);
101  break;
102 
103  case D_NONE:
104  str[0] = 0;
105  if(a->name != D_NONE || a->reg != NREG || a->sym != S)
106  sprint(str, "%N(R%d)(NONE)", a, a->reg);
107  break;
108 
109  case D_CONST:
110  if(a->reg == NREG || a->reg == REGZERO)
111  sprint(str, "$%N", a);
112  else
113  sprint(str, "$%N(R%d)", a, a->reg);
114  break;
115 
116  case D_SHIFT:
117  v = a->offset;
118  op = "<<>>->@>" + (((v>>22) & 3) << 1);
119  sprint(str, "R%ld%c%c%ld", (v>>16)&0x1F, op[0], op[1], (v>>10)&0x3F);
120  if(a->reg != NREG)
121  sprint(str+strlen(str), "(R%d)", a->reg);
122  break;
123 
124  case D_OCONST:
125  sprint(str, "$*$%N", a);
126  if(a->reg != NREG)
127  sprint(str, "%N(R%d)(CONST)", a, a->reg);
128  break;
129 
130  case D_OREG:
131  if(a->reg != NREG)
132  sprint(str, "%N(R%d)", a, a->reg);
133  else
134  sprint(str, "%N", a);
135  break;
136 
137  case D_XPRE:
138  if(a->reg != NREG)
139  sprint(str, "%N(R%d)!", a, a->reg);
140  else
141  sprint(str, "%N!", a);
142  break;
143 
144  case D_XPOST:
145  if(a->reg != NREG)
146  sprint(str, "(R%d)%N!", a->reg, a);
147  else
148  sprint(str, "%N!", a);
149  break;
150 
151  case D_EXTREG:
152  v = a->offset;
153  if(v & (7<<10))
154  snprint(str, sizeof(str), "R%ld%s<<%ld", (v>>16)&31, extop[(v>>13)&7], (v>>10)&7);
155  else
156  snprint(str, sizeof(str), "R%ld%s", (v>>16)&31, extop[(v>>13)&7]);
157  break;
158 
159  case D_ROFF:
160  v = a->offset;
161  if(v & (1<<16))
162  snprint(str, sizeof(str), "(R%d)[R%ld%s]", a->reg, v&31, extop[(v>>8)&7]);
163  else
164  snprint(str, sizeof(str), "(R%d)(R%ld%s)", a->reg, v&31, extop[(v>>8)&7]);
165  break;
166 
167  case D_REG:
168  sprint(str, "R%d", a->reg);
169  if(a->name != D_NONE || a->sym != S)
170  sprint(str, "%N(R%d)(REG)", a, a->reg);
171  break;
172 
173  case D_SP:
174  if(a->name != D_NONE || a->sym != S)
175  sprint(str, "%N(R%d)(REG)", a, a->reg);
176  else
177  strcpy(str, "SP");
178  break;
179 
180  case D_COND:
181  strcpy(str, strcond[a->reg & 0xF]);
182  break;
183 
184  case D_FREG:
185  sprint(str, "F%d", a->reg);
186  if(a->name != D_NONE || a->sym != S)
187  sprint(str, "%N(R%d)(REG)", a, a->reg);
188  break;
189 
190  case D_SPR:
191  switch((ulong)a->offset){
192  case D_FPSR:
193  sprint(str, "FPSR");
194  break;
195  case D_FPCR:
196  sprint(str, "FPCR");
197  break;
198  case D_NZCV:
199  sprint(str, "NZCV");
200  break;
201  default:
202  sprint(str, "SPR(%#llux)", a->offset);
203  break;
204  }
205  if(a->name != D_NONE || a->sym != S)
206  sprint(str, "%N(SPR%lld)(REG)", a, a->offset);
207  break;
208 
209  case D_BRANCH: /* botch */
210  if(curp->cond != P) {
211  v = curp->cond->pc;
212  if(a->sym != S)
213  sprint(str, "%s+%#.5lux(BRANCH)", a->sym->name, v);
214  else
215  sprint(str, "%.5lux(BRANCH)", v);
216  } else
217  if(a->sym != S)
218  sprint(str, "%s+%lld(APC)", a->sym->name, a->offset);
219  else
220  sprint(str, "%lld(APC)", a->offset);
221  break;
222 
223  case D_FCONST:
224  sprint(str, "$%e", ieeedtod(a->ieee));
225  break;
226 
227  case D_SCONST:
228  sprint(str, "$\"%S\"", a->sval);
229  break;
230  }
231  return fmtstrcpy(fp, str);
232 }
233 
234 int
235 Nconv(Fmt *fp)
236 {
237  char str[STRINGSZ];
238  Adr *a;
239  Sym *s;
240 
241  a = va_arg(fp->args, Adr*);
242  s = a->sym;
243  switch(a->name) {
244  default:
245  sprint(str, "GOK-name(%d)", a->name);
246  break;
247 
248  case D_NONE:
249  sprint(str, "%lld", a->offset);
250  break;
251 
252  case D_EXTERN:
253  if(s == S)
254  sprint(str, "%lld(SB)", a->offset);
255  else
256  sprint(str, "%s+%lld(SB)", s->name, a->offset);
257  break;
258 
259  case D_STATIC:
260  if(s == S)
261  sprint(str, "<>+%lld(SB)", a->offset);
262  else
263  sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
264  break;
265 
266  case D_AUTO:
267  if(s == S)
268  sprint(str, "%lld(SP)", a->offset);
269  else
270  sprint(str, "%s-%lld(SP)", s->name, -a->offset);
271  break;
272 
273  case D_PARAM:
274  if(s == S)
275  sprint(str, "%lld(FP)", a->offset);
276  else
277  sprint(str, "%s+%lld(FP)", s->name, a->offset);
278  break;
279  }
280  return fmtstrcpy(fp, str);
281 }
282 
283 int
284 Rconv(Fmt *fp)
285 {
286  char *s;
287  int a;
288 
289  a = va_arg(fp->args, int);
290  s = "C_??";
291  if(a >= C_NONE && a <= C_NCLASS)
292  s = cnames[a];
293  return fmtstrcpy(fp, s);
294 }
295 
296 void
297 prasm(Prog *p)
298 {
299  print("%P\n", p);
300 }
301 
302 int
303 Sconv(Fmt *fp)
304 {
305  int i, c;
306  char str[STRINGSZ], *p, *a;
307 
308  a = va_arg(fp->args, char*);
309  p = str;
310  for(i=0; i<sizeof(long); i++) {
311  c = a[i] & 0xff;
312  if(c >= 'a' && c <= 'z' ||
313  c >= 'A' && c <= 'Z' ||
314  c >= '0' && c <= '9' ||
315  c == ' ' || c == '%') {
316  *p++ = c;
317  continue;
318  }
319  *p++ = '\\';
320  switch(c) {
321  case 0:
322  *p++ = 'z';
323  continue;
324  case '\\':
325  case '"':
326  *p++ = c;
327  continue;
328  case '\n':
329  *p++ = 'n';
330  continue;
331  case '\t':
332  *p++ = 't';
333  continue;
334  }
335  *p++ = (c>>6) + '0';
336  *p++ = ((c>>3) & 7) + '0';
337  *p++ = (c & 7) + '0';
338  }
339  *p = 0;
340  return fmtstrcpy(fp, str);
341 }
342 
343 void
344 diag(char *fmt, ...)
345 {
346  char buf[STRINGSZ], *tn;
347  va_list arg;
348 
349  tn = "??none??";
350  if(curtext != P && curtext->from.sym != S)
351  tn = curtext->from.sym->name;
352  va_start(arg, fmt);
353  vseprint(buf, buf+sizeof(buf), fmt, arg);
354  va_end(arg);
355  print("%s: %s\n", tn, buf);
356 
357  nerrors++;
358  if(nerrors > 10) {
359  print("too many errors\n");
360  errorexit();
361  }
362 }