github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/5c/list.c (about)

     1  // Inferno utils/5c/list.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/5c/list.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  
    32  #define	EXTERN
    33  #include "gc.h"
    34  
    35  void
    36  listinit(void)
    37  {
    38  
    39  	fmtinstall('A', Aconv);
    40  	fmtinstall('P', Pconv);
    41  	fmtinstall('S', Sconv);
    42  	fmtinstall('N', Nconv);
    43  	fmtinstall('B', Bconv);
    44  	fmtinstall('D', Dconv);
    45  	fmtinstall('R', Rconv);
    46  }
    47  
    48  int
    49  Bconv(Fmt *fp)
    50  {
    51  	char str[STRINGSZ], ss[STRINGSZ], *s;
    52  	Bits bits;
    53  	int i;
    54  
    55  	str[0] = 0;
    56  	bits = va_arg(fp->args, Bits);
    57  	while(bany(&bits)) {
    58  		i = bnum(bits);
    59  		if(str[0])
    60  			strcat(str, " ");
    61  		if(var[i].sym == S) {
    62  			sprint(ss, "$%d", var[i].offset);
    63  			s = ss;
    64  		} else
    65  			s = var[i].sym->name;
    66  		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
    67  			break;
    68  		strcat(str, s);
    69  		bits.b[i/32] &= ~(1L << (i%32));
    70  	}
    71  	return fmtstrcpy(fp, str);
    72  }
    73  
    74  char *extra [] = {
    75  	".EQ", ".NE", ".CS", ".CC",
    76  	".MI", ".PL", ".VS", ".VC",
    77  	".HI", ".LS", ".GE", ".LT",
    78  	".GT", ".LE", "", ".NV",
    79  };
    80  
    81  int
    82  Pconv(Fmt *fp)
    83  {
    84  	char str[STRINGSZ], sc[20];
    85  	Prog *p;
    86  	int a, s;
    87  
    88  	p = va_arg(fp->args, Prog*);
    89  	a = p->as;
    90  	s = p->scond;
    91  	strcpy(sc, extra[s & C_SCOND]);
    92  	if(s & C_SBIT)
    93  		strcat(sc, ".S");
    94  	if(s & C_PBIT)
    95  		strcat(sc, ".P");
    96  	if(s & C_WBIT)
    97  		strcat(sc, ".W");
    98  	if(s & C_UBIT)		/* ambiguous with FBIT */
    99  		strcat(sc, ".U");
   100  	if(a == AMOVM) {
   101  		if(p->from.type == D_CONST)
   102  			sprint(str, "	%A%s	%R,%D", a, sc, &p->from, &p->to);
   103  		else
   104  		if(p->to.type == D_CONST)
   105  			sprint(str, "	%A%s	%D,%R", a, sc, &p->from, &p->to);
   106  		else
   107  			sprint(str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
   108  	} else
   109  	if(a == ADATA)
   110  		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
   111  	else
   112  	if(p->as == ATEXT)
   113  		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
   114  	else
   115  	if(p->reg == NREG)
   116  		sprint(str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
   117  	else
   118  	if(p->from.type != D_FREG)
   119  		sprint(str, "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
   120  	else
   121  		sprint(str, "	%A%s	%D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
   122  	return fmtstrcpy(fp, str);
   123  }
   124  
   125  int
   126  Aconv(Fmt *fp)
   127  {
   128  	char *s;
   129  	int a;
   130  
   131  	a = va_arg(fp->args, int);
   132  	s = "???";
   133  	if(a >= AXXX && a < ALAST)
   134  		s = anames[a];
   135  	return fmtstrcpy(fp, s);
   136  }
   137  
   138  int
   139  Dconv(Fmt *fp)
   140  {
   141  	char str[STRINGSZ];
   142  	Adr *a;
   143  	const char *op;
   144  	int v;
   145  
   146  	a = va_arg(fp->args, Adr*);
   147  	switch(a->type) {
   148  
   149  	default:
   150  		sprint(str, "GOK-type(%d)", a->type);
   151  		break;
   152  
   153  	case D_NONE:
   154  		str[0] = 0;
   155  		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   156  			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   157  		break;
   158  
   159  	case D_CONST:
   160  		if(a->reg != NREG)
   161  			sprint(str, "$%N(R%d)", a, a->reg);
   162  		else
   163  			sprint(str, "$%N", a);
   164  		break;
   165  
   166  	case D_CONST2:
   167  		sprint(str, "$%d-%d", a->offset, a->offset2);
   168  		break;
   169  
   170  	case D_SHIFT:
   171  		v = a->offset;
   172  		op = &"<<>>->@>"[(((v>>5) & 3) << 1)];
   173  		if(v & (1<<4))
   174  			sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
   175  		else
   176  			sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
   177  		if(a->reg != NREG)
   178  			sprint(str+strlen(str), "(R%d)", a->reg);
   179  		break;
   180  
   181  	case D_OREG:
   182  		if(a->reg != NREG)
   183  			sprint(str, "%N(R%d)", a, a->reg);
   184  		else
   185  			sprint(str, "%N", a);
   186  		break;
   187  
   188  	case D_REG:
   189  		sprint(str, "R%d", a->reg);
   190  		if(a->name != D_NONE || a->sym != S)
   191  			sprint(str, "%N(R%d)(REG)", a, a->reg);
   192  		break;
   193  
   194  	case D_FREG:
   195  		sprint(str, "F%d", a->reg);
   196  		if(a->name != D_NONE || a->sym != S)
   197  			sprint(str, "%N(R%d)(REG)", a, a->reg);
   198  		break;
   199  
   200  	case D_PSR:
   201  		sprint(str, "PSR");
   202  		if(a->name != D_NONE || a->sym != S)
   203  			sprint(str, "%N(PSR)(REG)", a);
   204  		break;
   205  
   206  	case D_BRANCH:
   207  		sprint(str, "%d(PC)", a->offset-pc);
   208  		break;
   209  
   210  	case D_FCONST:
   211  		sprint(str, "$%.17e", a->dval);
   212  		break;
   213  
   214  	case D_SCONST:
   215  		sprint(str, "$\"%S\"", a->sval);
   216  		break;
   217  	}
   218  	return fmtstrcpy(fp, str);
   219  }
   220  
   221  int
   222  Rconv(Fmt *fp)
   223  {
   224  	char str[STRINGSZ];
   225  	Adr *a;
   226  	int i, v;
   227  
   228  	a = va_arg(fp->args, Adr*);
   229  	sprint(str, "GOK-reglist");
   230  	switch(a->type) {
   231  	case D_CONST:
   232  	case D_CONST2:
   233  		if(a->reg != NREG)
   234  			break;
   235  		if(a->sym != S)
   236  			break;
   237  		v = a->offset;
   238  		strcpy(str, "");
   239  		for(i=0; i<NREG; i++) {
   240  			if(v & (1<<i)) {
   241  				if(str[0] == 0)
   242  					strcat(str, "[R");
   243  				else
   244  					strcat(str, ",R");
   245  				sprint(strchr(str, 0), "%d", i);
   246  			}
   247  		}
   248  		strcat(str, "]");
   249  	}
   250  	return fmtstrcpy(fp, str);
   251  }
   252  
   253  int
   254  Sconv(Fmt *fp)
   255  {
   256  	int i, c;
   257  	char str[STRINGSZ], *p, *a;
   258  
   259  	a = va_arg(fp->args, char*);
   260  	p = str;
   261  	for(i=0; i<NSNAME; i++) {
   262  		c = a[i] & 0xff;
   263  		if(c >= 'a' && c <= 'z' ||
   264  		   c >= 'A' && c <= 'Z' ||
   265  		   c >= '0' && c <= '9' ||
   266  		   c == ' ' || c == '%') {
   267  			*p++ = c;
   268  			continue;
   269  		}
   270  		*p++ = '\\';
   271  		switch(c) {
   272  		case 0:
   273  			*p++ = 'z';
   274  			continue;
   275  		case '\\':
   276  		case '"':
   277  			*p++ = c;
   278  			continue;
   279  		case '\n':
   280  			*p++ = 'n';
   281  			continue;
   282  		case '\t':
   283  			*p++ = 't';
   284  			continue;
   285  		case '\r':
   286  			*p++ = 'r';
   287  			continue;
   288  		case '\f':
   289  			*p++ = 'f';
   290  			continue;
   291  		}
   292  		*p++ = (c>>6) + '0';
   293  		*p++ = ((c>>3) & 7) + '0';
   294  		*p++ = (c & 7) + '0';
   295  	}
   296  	*p = 0;
   297  	return fmtstrcpy(fp, str);
   298  }
   299  
   300  int
   301  Nconv(Fmt *fp)
   302  {
   303  	char str[STRINGSZ];
   304  	Adr *a;
   305  	Sym *s;
   306  
   307  	a = va_arg(fp->args, Adr*);
   308  	s = a->sym;
   309  	if(s == S) {
   310  		sprint(str, "%d", a->offset);
   311  		goto out;
   312  	}
   313  	switch(a->name) {
   314  	default:
   315  		sprint(str, "GOK-name(%d)", a->name);
   316  		break;
   317  
   318  	case D_NONE:
   319  		sprint(str, "%d", a->offset);
   320  		break;
   321  
   322  	case D_EXTERN:
   323  		sprint(str, "%s+%d(SB)", s->name, a->offset);
   324  		break;
   325  
   326  	case D_STATIC:
   327  		sprint(str, "%s<>+%d(SB)", s->name, a->offset);
   328  		break;
   329  
   330  	case D_AUTO:
   331  		sprint(str, "%s-%d(SP)", s->name, -a->offset);
   332  		break;
   333  
   334  	case D_PARAM:
   335  		sprint(str, "%s+%d(FP)", s->name, a->offset);
   336  		break;
   337  	}
   338  out:
   339  	return fmtstrcpy(fp, str);
   340  }