The Go Programming Language

Text file src/cmd/8g/list.c

     1	// Derived from Inferno utils/8c/list.c
     2	// http://code.google.com/p/inferno-os/source/browse/utils/8c/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 "gg.h"
    32	
    33	static	int	sconsize;
    34	void
    35	listinit(void)
    36	{
    37	
    38		fmtinstall('A', Aconv);		// as
    39		fmtinstall('P', Pconv);		// Prog*
    40		fmtinstall('D', Dconv);		// Addr*
    41		fmtinstall('R', Rconv);		// reg
    42		fmtinstall('Y', Yconv);		// sconst
    43	}
    44	
    45	int
    46	Pconv(Fmt *fp)
    47	{
    48		char str[STRINGSZ];
    49		Prog *p;
    50		char scale[40];
    51	
    52		p = va_arg(fp->args, Prog*);
    53		sconsize = 8;
    54		scale[0] = '\0';
    55		if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
    56			snprint(scale, sizeof scale, "%d,", p->from.scale);
    57		switch(p->as) {
    58		default:
    59			snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%D",
    60				p->loc, p->lineno, p->as, &p->from, scale, &p->to);
    61			break;
    62	
    63		case ADATA:
    64			sconsize = p->from.scale;
    65			snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
    66				p->loc, p->lineno, p->as, &p->from, sconsize, &p->to);
    67			break;
    68	
    69		case ATEXT:
    70			snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%lD",
    71				p->loc, p->lineno, p->as, &p->from, scale, &p->to);
    72			break;
    73		}
    74		return fmtstrcpy(fp, str);
    75	}
    76	
    77	int
    78	Dconv(Fmt *fp)
    79	{
    80		char str[STRINGSZ], s[STRINGSZ];
    81		Addr *a;
    82		int i;
    83		uint32 d1, d2;
    84	
    85		a = va_arg(fp->args, Addr*);
    86		i = a->type;
    87		if(i >= D_INDIR) {
    88			if(a->offset)
    89				snprint(str, sizeof(str), "%d(%R)", a->offset, i-D_INDIR);
    90			else
    91				snprint(str, sizeof(str), "(%R)", i-D_INDIR);
    92			goto brk;
    93		}
    94		switch(i) {
    95	
    96		default:
    97			if(a->offset)
    98				snprint(str, sizeof(str), "$%d,%R", a->offset, i);
    99			else
   100				snprint(str, sizeof(str), "%R", i);
   101			break;
   102	
   103		case D_NONE:
   104			str[0] = 0;
   105			break;
   106	
   107		case D_BRANCH:
   108			snprint(str, sizeof(str), "%d", a->branch->loc);
   109			break;
   110	
   111		case D_EXTERN:
   112			snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
   113			break;
   114	
   115		case D_STATIC:
   116			snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
   117			break;
   118	
   119		case D_AUTO:
   120			snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
   121			break;
   122	
   123		case D_PARAM:
   124			snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
   125			break;
   126	
   127		case D_CONST:
   128			if(fp->flags & FmtLong) {
   129				d1 = a->offset;
   130				d2 = a->offset2;
   131				snprint(str, sizeof(str), "$%ud-%ud", (ulong)d1, (ulong)d2);
   132				break;
   133			}
   134			snprint(str, sizeof(str), "$%d", a->offset);
   135			break;
   136	
   137		case D_FCONST:
   138			snprint(str, sizeof(str), "$(%.17e)", a->dval);
   139			break;
   140	
   141		case D_SCONST:
   142			snprint(str, sizeof(str), "$\"%Y\"", a->sval);
   143			break;
   144	
   145		case D_ADDR:
   146			a->type = a->index;
   147			a->index = D_NONE;
   148			snprint(str, sizeof(str), "$%D", a);
   149			a->index = a->type;
   150			a->type = D_ADDR;
   151			goto conv;
   152		}
   153	brk:
   154		if(a->index != D_NONE) {
   155			snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
   156			strcat(str, s);
   157		}
   158	conv:
   159		return fmtstrcpy(fp, str);
   160	}
   161	
   162	static	char*	regstr[] =
   163	{
   164		"AL",		/* [D_AL] */
   165		"CL",
   166		"DL",
   167		"BL",
   168	
   169		"AH",	/* [D_AH] */
   170		"CH",
   171		"DH",
   172		"BH",
   173	
   174		"AX",		/* [D_AX] */
   175		"CX",
   176		"DX",
   177		"BX",
   178		"SP",
   179		"BP",
   180		"SI",
   181		"DI",
   182	
   183		"F0",		/* [D_F0] */
   184		"F1",
   185		"F2",
   186		"F3",
   187		"F4",
   188		"F5",
   189		"F6",
   190		"F7",
   191	
   192		"CS",		/* [D_CS] */
   193		"SS",
   194		"DS",
   195		"ES",
   196		"FS",
   197		"GS",
   198	
   199		"GDTR",		/* [D_GDTR] */
   200		"IDTR",		/* [D_IDTR] */
   201		"LDTR",		/* [D_LDTR] */
   202		"MSW",		/* [D_MSW] */
   203		"TASK",		/* [D_TASK] */
   204	
   205		"CR0",		/* [D_CR] */
   206		"CR1",
   207		"CR2",
   208		"CR3",
   209		"CR4",
   210		"CR5",
   211		"CR6",
   212		"CR7",
   213	
   214		"DR0",		/* [D_DR] */
   215		"DR1",
   216		"DR2",
   217		"DR3",
   218		"DR4",
   219		"DR5",
   220		"DR6",
   221		"DR7",
   222	
   223		"TR0",		/* [D_TR] */
   224		"TR1",
   225		"TR2",
   226		"TR3",
   227		"TR4",
   228		"TR5",
   229		"TR6",
   230		"TR7",
   231	
   232		"NONE",		/* [D_NONE] */
   233	};
   234	
   235	int
   236	Rconv(Fmt *fp)
   237	{
   238		char str[STRINGSZ];
   239		int r;
   240	
   241		r = va_arg(fp->args, int);
   242		if(r < 0 || r >= nelem(regstr) || regstr[r] == nil) {
   243			snprint(str, sizeof(str), "BAD_R(%d)", r);
   244			return fmtstrcpy(fp, str);
   245		}
   246		return fmtstrcpy(fp, regstr[r]);
   247	}
   248	
   249	int
   250	Aconv(Fmt *fp)
   251	{
   252		int i;
   253	
   254		i = va_arg(fp->args, int);
   255		return fmtstrcpy(fp, anames[i]);
   256	}
   257	
   258	
   259	int
   260	Yconv(Fmt *fp)
   261	{
   262		int i, c;
   263		char str[STRINGSZ], *p, *a;
   264	
   265		a = va_arg(fp->args, char*);
   266		p = str;
   267		for(i=0; i<sconsize; i++) {
   268			c = a[i] & 0xff;
   269			if((c >= 'a' && c <= 'z') ||
   270			   (c >= 'A' && c <= 'Z') ||
   271			   (c >= '0' && c <= '9')) {
   272				*p++ = c;
   273				continue;
   274			}
   275			*p++ = '\\';
   276			switch(c) {
   277			default:
   278				if(c < 040 || c >= 0177)
   279					break;	/* not portable */
   280				p[-1] = c;
   281				continue;
   282			case 0:
   283				*p++ = 'z';
   284				continue;
   285			case '\\':
   286			case '"':
   287				*p++ = c;
   288				continue;
   289			case '\n':
   290				*p++ = 'n';
   291				continue;
   292			case '\t':
   293				*p++ = 't';
   294				continue;
   295			}
   296			*p++ = (c>>6) + '0';
   297			*p++ = ((c>>3) & 7) + '0';
   298			*p++ = (c & 7) + '0';
   299		}
   300		*p = 0;
   301		return fmtstrcpy(fp, str);
   302	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.