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

     1  // Derived from Inferno utils/6c/list.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6c/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  static	int	sconsize;
    36  void
    37  listinit(void)
    38  {
    39  
    40  	fmtinstall('A', Aconv);		// as
    41  	fmtinstall('P', Pconv);		// Prog*
    42  	fmtinstall('D', Dconv);		// Addr*
    43  	fmtinstall('R', Rconv);		// reg
    44  	fmtinstall('Y', Yconv);		// sconst
    45  }
    46  
    47  int
    48  Pconv(Fmt *fp)
    49  {
    50  	char str[STRINGSZ];
    51  	Prog *p;
    52  	char scale[40];
    53  
    54  	p = va_arg(fp->args, Prog*);
    55  	sconsize = 8;
    56  	scale[0] = '\0';
    57  	if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
    58  		snprint(scale, sizeof scale, "%d,", p->from.scale);
    59  	switch(p->as) {
    60  	default:
    61  		snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%D",
    62  			p->loc, p->lineno, p->as, &p->from, scale, &p->to);
    63  		break;
    64  
    65  	case ADATA:
    66  		sconsize = p->from.scale;
    67  		snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
    68  			p->loc, p->lineno, p->as, &p->from, sconsize, &p->to);
    69  		break;
    70  
    71  	case ATEXT:
    72  		snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%lD",
    73  			p->loc, p->lineno, p->as, &p->from, scale, &p->to);
    74  		break;
    75  	}
    76  	return fmtstrcpy(fp, str);
    77  }
    78  
    79  int
    80  Dconv(Fmt *fp)
    81  {
    82  	char str[STRINGSZ], s[STRINGSZ];
    83  	Addr *a;
    84  	int i;
    85  	uint32 d1, d2;
    86  
    87  	a = va_arg(fp->args, Addr*);
    88  	i = a->type;
    89  	if(i >= D_INDIR) {
    90  		if(a->offset)
    91  			snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR);
    92  		else
    93  			snprint(str, sizeof(str), "(%R)", i-D_INDIR);
    94  		goto brk;
    95  	}
    96  	switch(i) {
    97  
    98  	default:
    99  		if(a->offset)
   100  			snprint(str, sizeof(str), "$%lld,%R", a->offset, i);
   101  		else
   102  			snprint(str, sizeof(str), "%R", i);
   103  		break;
   104  
   105  	case D_NONE:
   106  		str[0] = 0;
   107  		break;
   108  
   109  	case D_BRANCH:
   110  		if(a->u.branch == nil)
   111  			snprint(str, sizeof(str), "<nil>");
   112  		else
   113  			snprint(str, sizeof(str), "%d", a->u.branch->loc);
   114  		break;
   115  
   116  	case D_EXTERN:
   117  		snprint(str, sizeof(str), "%S+%lld(SB)", a->sym, a->offset);
   118  		break;
   119  
   120  	case D_STATIC:
   121  		snprint(str, sizeof(str), "%S<>+%lld(SB)", a->sym, a->offset);
   122  		break;
   123  
   124  	case D_AUTO:
   125  		snprint(str, sizeof(str), "%S+%lld(SP)", a->sym, a->offset);
   126  		break;
   127  
   128  	case D_PARAM:
   129  		snprint(str, sizeof(str), "%S+%lld(FP)", a->sym, a->offset);
   130  		break;
   131  
   132  	case D_CONST:
   133  		if(fp->flags & FmtLong) {
   134  			d1 = a->offset & 0xffffffffLL;
   135  			d2 = (a->offset>>32) & 0xffffffffLL;
   136  			snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2);
   137  			break;
   138  		}
   139  		snprint(str, sizeof(str), "$%lld", a->offset);
   140  		break;
   141  
   142  	case D_FCONST:
   143  		snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
   144  		break;
   145  
   146  	case D_SCONST:
   147  		snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
   148  		break;
   149  
   150  	case D_ADDR:
   151  		a->type = a->index;
   152  		a->index = D_NONE;
   153  		snprint(str, sizeof(str), "$%D", a);
   154  		a->index = a->type;
   155  		a->type = D_ADDR;
   156  		goto conv;
   157  	}
   158  brk:
   159  	if(a->index != D_NONE) {
   160  		snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
   161  		strcat(str, s);
   162  	}
   163  conv:
   164  	fmtstrcpy(fp, str);
   165  	if(a->gotype)
   166  		fmtprint(fp, "{%s}", a->gotype->name);
   167  	return 0;
   168  }
   169  
   170  static	char*	regstr[] =
   171  {
   172  	"AL",		/* [D_AL] */
   173  	"CL",
   174  	"DL",
   175  	"BL",
   176  	"SPB",
   177  	"BPB",
   178  	"SIB",
   179  	"DIB",
   180  	"R8B",
   181  	"R9B",
   182  	"R10B",
   183  	"R11B",
   184  	"R12B",
   185  	"R13B",
   186  	"R14B",
   187  	"R15B",
   188  
   189  	"AX",		/* [D_AX] */
   190  	"CX",
   191  	"DX",
   192  	"BX",
   193  	"SP",
   194  	"BP",
   195  	"SI",
   196  	"DI",
   197  	"R8",
   198  	"R9",
   199  	"R10",
   200  	"R11",
   201  	"R12",
   202  	"R13",
   203  	"R14",
   204  	"R15",
   205  
   206  	"AH",
   207  	"CH",
   208  	"DH",
   209  	"BH",
   210  
   211  	"F0",		/* [D_F0] */
   212  	"F1",
   213  	"F2",
   214  	"F3",
   215  	"F4",
   216  	"F5",
   217  	"F6",
   218  	"F7",
   219  
   220  	"M0",
   221  	"M1",
   222  	"M2",
   223  	"M3",
   224  	"M4",
   225  	"M5",
   226  	"M6",
   227  	"M7",
   228  
   229  	"X0",
   230  	"X1",
   231  	"X2",
   232  	"X3",
   233  	"X4",
   234  	"X5",
   235  	"X6",
   236  	"X7",
   237  	"X8",
   238  	"X9",
   239  	"X10",
   240  	"X11",
   241  	"X12",
   242  	"X13",
   243  	"X14",
   244  	"X15",
   245  
   246  	"CS",		/* [D_CS] */
   247  	"SS",
   248  	"DS",
   249  	"ES",
   250  	"FS",
   251  	"GS",
   252  
   253  	"GDTR",		/* [D_GDTR] */
   254  	"IDTR",		/* [D_IDTR] */
   255  	"LDTR",		/* [D_LDTR] */
   256  	"MSW",		/* [D_MSW] */
   257  	"TASK",		/* [D_TASK] */
   258  
   259  	"CR0",		/* [D_CR] */
   260  	"CR1",
   261  	"CR2",
   262  	"CR3",
   263  	"CR4",
   264  	"CR5",
   265  	"CR6",
   266  	"CR7",
   267  	"CR8",
   268  	"CR9",
   269  	"CR10",
   270  	"CR11",
   271  	"CR12",
   272  	"CR13",
   273  	"CR14",
   274  	"CR15",
   275  
   276  	"DR0",		/* [D_DR] */
   277  	"DR1",
   278  	"DR2",
   279  	"DR3",
   280  	"DR4",
   281  	"DR5",
   282  	"DR6",
   283  	"DR7",
   284  
   285  	"TR0",		/* [D_TR] */
   286  	"TR1",
   287  	"TR2",
   288  	"TR3",
   289  	"TR4",
   290  	"TR5",
   291  	"TR6",
   292  	"TR7",
   293  
   294  	"NONE",		/* [D_NONE] */
   295  };
   296  
   297  int
   298  Rconv(Fmt *fp)
   299  {
   300  	char str[STRINGSZ];
   301  	int r;
   302  
   303  	r = va_arg(fp->args, int);
   304  	if(r < 0 || r >= nelem(regstr) || regstr[r] == nil) {
   305  		snprint(str, sizeof(str), "BAD_R(%d)", r);
   306  		return fmtstrcpy(fp, str);
   307  	}
   308  	return fmtstrcpy(fp, regstr[r]);
   309  }
   310  
   311  int
   312  Aconv(Fmt *fp)
   313  {
   314  	int i;
   315  
   316  	i = va_arg(fp->args, int);
   317  	return fmtstrcpy(fp, anames[i]);
   318  }
   319  
   320  
   321  int
   322  Yconv(Fmt *fp)
   323  {
   324  	int i, c;
   325  	char str[STRINGSZ], *p, *a;
   326  
   327  	a = va_arg(fp->args, char*);
   328  	p = str;
   329  	for(i=0; i<sconsize; i++) {
   330  		c = a[i] & 0xff;
   331  		if((c >= 'a' && c <= 'z') ||
   332  		   (c >= 'A' && c <= 'Z') ||
   333  		   (c >= '0' && c <= '9')) {
   334  			*p++ = c;
   335  			continue;
   336  		}
   337  		*p++ = '\\';
   338  		switch(c) {
   339  		default:
   340  			if(c < 040 || c >= 0177)
   341  				break;	/* not portable */
   342  			p[-1] = c;
   343  			continue;
   344  		case 0:
   345  			*p++ = 'z';
   346  			continue;
   347  		case '\\':
   348  		case '"':
   349  			*p++ = c;
   350  			continue;
   351  		case '\n':
   352  			*p++ = 'n';
   353  			continue;
   354  		case '\t':
   355  			*p++ = 't';
   356  			continue;
   357  		}
   358  		*p++ = (c>>6) + '0';
   359  		*p++ = ((c>>3) & 7) + '0';
   360  		*p++ = (c & 7) + '0';
   361  	}
   362  	*p = 0;
   363  	return fmtstrcpy(fp, str);
   364  }