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

     1  // Derived from 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  #include <u.h>
    32  #include <libc.h>
    33  #include "gg.h"
    34  
    35  // TODO(kaib): make 5g/list.c congruent with 5l/list.c
    36  
    37  static	int	sconsize;
    38  void
    39  listinit(void)
    40  {
    41  
    42  	fmtinstall('A', Aconv);		// as
    43  	fmtinstall('C', Cconv);		// conditional execution bit
    44  	fmtinstall('P', Pconv);			// Prog*
    45  	fmtinstall('D', Dconv);		// Addr*
    46  	fmtinstall('Y', Yconv);		// sconst
    47  	fmtinstall('R', Rconv);		// register
    48  	fmtinstall('M', Mconv);		// names
    49  }
    50  
    51  int
    52  Pconv(Fmt *fp)
    53  {
    54  	char str[STRINGSZ], str1[STRINGSZ];
    55  	Prog *p;
    56  
    57  	p = va_arg(fp->args, Prog*);
    58  	sconsize = 8;
    59  	switch(p->as) {
    60  	default:
    61  		snprint(str1, sizeof(str1), "%A%C", p->as, p->scond);
    62  		if(p->reg == NREG && p->as != AGLOBL)
    63  			snprint(str, sizeof(str), "%.4d (%L) %-7s	%D,%D", 
    64  				p->loc, p->lineno, str1, &p->from, &p->to);
    65  		else
    66  		if (p->from.type != D_FREG) {
    67  			snprint(str, sizeof(str), "%.4d (%L) %-7s	%D,R%d,%D", 
    68  				p->loc, p->lineno, str1, &p->from, p->reg, &p->to);
    69  		} else
    70  			snprint(str, sizeof(str), "%.4d (%L) %-7A%C	%D,F%d,%D",
    71  				p->loc, p->lineno, p->as, p->scond, &p->from, p->reg, &p->to);
    72  		break;
    73  
    74  	case ADATA:
    75  		snprint(str, sizeof(str), "%.4d (%L) %-7A	%D/%d,%D",
    76  			p->loc, p->lineno, p->as, &p->from, p->reg, &p->to);
    77  		break;
    78  	}
    79  	return fmtstrcpy(fp, str);
    80  }
    81  
    82  int
    83  Dconv(Fmt *fp)
    84  {
    85  	char str[STRINGSZ];
    86  	const char *op;
    87  	Addr *a;
    88  	int i;
    89  	int32 v;
    90  
    91  	a = va_arg(fp->args, Addr*);
    92  	if(a == A) {
    93  		sprint(str, "<nil>");
    94  		goto conv;
    95  	}
    96  	i = a->type;
    97  	switch(i) {
    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, "%M(R%d)(NONE)", a, a->reg);
   107  		break;
   108  
   109  	case D_CONST:
   110  		if(a->reg != NREG)
   111  			sprint(str, "$%M(R%d)", a, a->reg);
   112  		else
   113  			sprint(str, "$%M", a);
   114  		break;
   115  
   116  	case D_CONST2:
   117  		sprint(str, "$%d-%d", a->offset, a->offset2);
   118  		break;
   119  
   120  	case D_SHIFT:
   121  		v = a->offset;
   122  		op = &"<<>>->@>"[(((v>>5) & 3) << 1)];
   123  		if(v & (1<<4))
   124  			sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
   125  		else
   126  			sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
   127  		if(a->reg != NREG)
   128  			sprint(str+strlen(str), "(R%d)", a->reg);
   129  		break;
   130  
   131  	case D_OCONST:
   132  		sprint(str, "$*$%M", a);
   133  		if(a->reg != NREG)
   134  			sprint(str, "%M(R%d)(CONST)", a, a->reg);
   135  		break;
   136  
   137  	case D_OREG:
   138  		if(a->reg != NREG)
   139  			sprint(str, "%M(R%d)", a, a->reg);
   140  		else
   141  			sprint(str, "%M", a);
   142  		break;
   143  
   144  	case D_REG:
   145  		sprint(str, "R%d", a->reg);
   146  		if(a->name != D_NONE || a->sym != S)
   147  			sprint(str, "%M(R%d)(REG)", a, a->reg);
   148  		break;
   149  
   150  	case D_REGREG:
   151  		sprint(str, "(R%d,R%d)", a->reg, (int)a->offset);
   152  		if(a->name != D_NONE || a->sym != S)
   153  			sprint(str, "%M(R%d)(REG)", a, a->reg);
   154  		break;
   155  
   156  	case D_REGREG2:
   157  		sprint(str, "R%d,R%d", a->reg, (int)a->offset);
   158  		if(a->name != D_NONE || a->sym != S)
   159  			sprint(str, "%M(R%d)(REG)", a, a->reg);
   160  		break;
   161  
   162  	case D_FREG:
   163  		sprint(str, "F%d", a->reg);
   164  		if(a->name != D_NONE || a->sym != S)
   165  			sprint(str, "%M(R%d)(REG)", a, a->reg);
   166  		break;
   167  
   168  	case D_BRANCH:
   169  		if(a->u.branch == P || a->u.branch->loc == 0) {
   170  			if(a->sym != S)
   171  				sprint(str, "%s+%d(APC)", a->sym->name, a->offset);
   172  			else
   173  				sprint(str, "%d(APC)", a->offset);
   174  		} else
   175  			if(a->sym != S)
   176  				sprint(str, "%s+%d(APC)", a->sym->name, a->u.branch->loc);
   177  			else
   178  				sprint(str, "%d(APC)", a->u.branch->loc);
   179  		break;
   180  
   181  	case D_FCONST:
   182  		snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
   183  		break;
   184  
   185  	case D_SCONST:
   186  		snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
   187  		break;
   188  
   189  		// TODO(kaib): Add back
   190  //	case D_ADDR:
   191  //		a->type = a->index;
   192  //		a->index = D_NONE;
   193  //		snprint(str, sizeof(str), "$%D", a);
   194  //		a->index = a->type;
   195  //		a->type = D_ADDR;
   196  //		goto conv;
   197  	}
   198  conv:
   199  	fmtstrcpy(fp, str);
   200  	if(a->gotype)
   201  		fmtprint(fp, "{%s}", a->gotype->name);
   202  	return 0;
   203  }
   204  
   205  int
   206  Aconv(Fmt *fp)
   207  {
   208  	int i;
   209  
   210  	i = va_arg(fp->args, int);
   211  	return fmtstrcpy(fp, anames[i]);
   212  }
   213  
   214  char*	strcond[16] =
   215  {
   216  	".EQ",
   217  	".NE",
   218  	".HS",
   219  	".LO",
   220  	".MI",
   221  	".PL",
   222  	".VS",
   223  	".VC",
   224  	".HI",
   225  	".LS",
   226  	".GE",
   227  	".LT",
   228  	".GT",
   229  	".LE",
   230  	"",
   231  	".NV"
   232  };
   233  
   234  int
   235  Cconv(Fmt *fp)
   236  {
   237  	char s[STRINGSZ];
   238  	int c;
   239  
   240  	c = va_arg(fp->args, int);
   241  	strcpy(s, strcond[c & C_SCOND]);
   242  	if(c & C_SBIT)
   243  		strcat(s, ".S");
   244  	if(c & C_PBIT)
   245  		strcat(s, ".P");
   246  	if(c & C_WBIT)
   247  		strcat(s, ".W");
   248  	if(c & C_UBIT)		/* ambiguous with FBIT */
   249  		strcat(s, ".U");
   250  	return fmtstrcpy(fp, s);
   251  }
   252  
   253  int
   254  Yconv(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<sconsize; i++) {
   262  		c = a[i] & 0xff;
   263  		if((c >= 'a' && c <= 'z') ||
   264  		   (c >= 'A' && c <= 'Z') ||
   265  		   (c >= '0' && c <= '9')) {
   266  			*p++ = c;
   267  			continue;
   268  		}
   269  		*p++ = '\\';
   270  		switch(c) {
   271  		default:
   272  			if(c < 040 || c >= 0177)
   273  				break;	/* not portable */
   274  			p[-1] = c;
   275  			continue;
   276  		case 0:
   277  			*p++ = 'z';
   278  			continue;
   279  		case '\\':
   280  		case '"':
   281  			*p++ = c;
   282  			continue;
   283  		case '\n':
   284  			*p++ = 'n';
   285  			continue;
   286  		case '\t':
   287  			*p++ = 't';
   288  			continue;
   289  		}
   290  		*p++ = (c>>6) + '0';
   291  		*p++ = ((c>>3) & 7) + '0';
   292  		*p++ = (c & 7) + '0';
   293  	}
   294  	*p = 0;
   295  	return fmtstrcpy(fp, str);
   296  }
   297  
   298  int
   299  Rconv(Fmt *fp)
   300  {
   301  	int r;
   302  	char str[STRINGSZ];
   303  
   304  	r = va_arg(fp->args, int);
   305  	snprint(str, sizeof(str), "R%d", r);
   306  	return fmtstrcpy(fp, str);
   307  }
   308  
   309  int
   310  Mconv(Fmt *fp)
   311  {
   312  	char str[STRINGSZ];
   313  	Addr *a;
   314  
   315  	a = va_arg(fp->args, Addr*);
   316  	switch(a->name) {
   317  	default:
   318  		snprint(str, sizeof(str),  "GOK-name(%d)", a->name);
   319  		break;
   320  
   321  	case D_NONE:
   322  		snprint(str, sizeof(str), "%d", a->offset);
   323  		break;
   324  
   325  	case D_EXTERN:
   326  		snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
   327  		break;
   328  
   329  	case D_STATIC:
   330  		snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
   331  		break;
   332  
   333  	case D_AUTO:
   334  		snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
   335  		break;
   336  
   337  	case D_PARAM:
   338  		snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
   339  		break;
   340  	}
   341  	return fmtstrcpy(fp, str);
   342  }