github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/src/cmd/8g/gobj.c (about)

     1  // Derived from Inferno utils/8c/swt.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/8c/swt.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  int
    36  dsname(Sym *s, int off, char *t, int n)
    37  {
    38  	Prog *p;
    39  
    40  	p = gins(ADATA, N, N);
    41  	p->from.type = D_EXTERN;
    42  	p->from.index = D_NONE;
    43  	p->from.offset = off;
    44  	p->from.scale = n;
    45  	p->from.sym = linksym(s);
    46  	
    47  	p->to.type = D_SCONST;
    48  	p->to.index = D_NONE;
    49  	memmove(p->to.u.sval, t, n);
    50  	return off + n;
    51  }
    52  
    53  /*
    54   * make a refer to the data s, s+len
    55   * emitting DATA if needed.
    56   */
    57  void
    58  datastring(char *s, int len, Addr *a)
    59  {
    60  	Sym *sym;
    61  	
    62  	sym = stringsym(s, len);
    63  	a->type = D_EXTERN;
    64  	a->sym = linksym(sym);
    65  	a->node = sym->def;
    66  	a->offset = widthptr+4;  // skip header
    67  	a->etype = TINT32;
    68  }
    69  
    70  /*
    71   * make a refer to the string sval,
    72   * emitting DATA if needed.
    73   */
    74  void
    75  datagostring(Strlit *sval, Addr *a)
    76  {
    77  	Sym *sym;
    78  	
    79  	sym = stringsym(sval->s, sval->len);
    80  	a->type = D_EXTERN;
    81  	a->sym = linksym(sym);
    82  	a->node = sym->def;
    83  	a->offset = 0;  // header
    84  	a->etype = TSTRING;
    85  }
    86  
    87  void
    88  gdata(Node *nam, Node *nr, int wid)
    89  {
    90  	Prog *p;
    91  	vlong v;
    92  
    93  	if(nr->op == OLITERAL) {
    94  		switch(nr->val.ctype) {
    95  		case CTCPLX:
    96  			gdatacomplex(nam, nr->val.u.cval);
    97  			return;
    98  		case CTSTR:
    99  			gdatastring(nam, nr->val.u.sval);
   100  			return;
   101  		}
   102  	}
   103  
   104  	if(wid == 8 && is64(nr->type)) {
   105  		v = mpgetfix(nr->val.u.xval);
   106  		p = gins(ADATA, nam, nodintconst(v));
   107  		p->from.scale = 4;
   108  		p = gins(ADATA, nam, nodintconst(v>>32));
   109  		p->from.scale = 4;
   110  		p->from.offset += 4;
   111  		return;
   112  	}
   113  	p = gins(ADATA, nam, nr);
   114  	p->from.scale = wid;
   115  }
   116  
   117  void
   118  gdatacomplex(Node *nam, Mpcplx *cval)
   119  {
   120  	Prog *p;
   121  	int w;
   122  
   123  	w = cplxsubtype(nam->type->etype);
   124  	w = types[w]->width;
   125  
   126  	p = gins(ADATA, nam, N);
   127  	p->from.scale = w;
   128  	p->to.type = D_FCONST;
   129  	p->to.u.dval = mpgetflt(&cval->real);
   130  
   131  	p = gins(ADATA, nam, N);
   132  	p->from.scale = w;
   133  	p->from.offset += w;
   134  	p->to.type = D_FCONST;
   135  	p->to.u.dval = mpgetflt(&cval->imag);
   136  }
   137  
   138  void
   139  gdatastring(Node *nam, Strlit *sval)
   140  {
   141  	Prog *p;
   142  	Node nod1;
   143  
   144  	p = gins(ADATA, nam, N);
   145  	datastring(sval->s, sval->len, &p->to);
   146  	p->from.scale = types[tptr]->width;
   147  	p->to.index = p->to.type;
   148  	p->to.type = D_ADDR;
   149  //print("%P\n", p);
   150  
   151  	nodconst(&nod1, types[TINT32], sval->len);
   152  	p = gins(ADATA, nam, &nod1);
   153  	p->from.scale = types[TINT32]->width;
   154  	p->from.offset += types[tptr]->width;
   155  }
   156  
   157  int
   158  dstringptr(Sym *s, int off, char *str)
   159  {
   160  	Prog *p;
   161  
   162  	off = rnd(off, widthptr);
   163  	p = gins(ADATA, N, N);
   164  	p->from.type = D_EXTERN;
   165  	p->from.index = D_NONE;
   166  	p->from.sym = linksym(s);
   167  	p->from.offset = off;
   168  	p->from.scale = widthptr;
   169  
   170  	datastring(str, strlen(str)+1, &p->to);
   171  	p->to.index = p->to.type;
   172  	p->to.type = D_ADDR;
   173  	p->to.etype = TINT32;
   174  	off += widthptr;
   175  
   176  	return off;
   177  }
   178  
   179  int
   180  dgostrlitptr(Sym *s, int off, Strlit *lit)
   181  {
   182  	Prog *p;
   183  
   184  	if(lit == nil)
   185  		return duintptr(s, off, 0);
   186  
   187  	off = rnd(off, widthptr);
   188  	p = gins(ADATA, N, N);
   189  	p->from.type = D_EXTERN;
   190  	p->from.index = D_NONE;
   191  	p->from.sym = linksym(s);
   192  	p->from.offset = off;
   193  	p->from.scale = widthptr;
   194  	datagostring(lit, &p->to);
   195  	p->to.index = p->to.type;
   196  	p->to.type = D_ADDR;
   197  	p->to.etype = TINT32;
   198  	off += widthptr;
   199  
   200  	return off;
   201  }
   202  
   203  int
   204  dgostringptr(Sym *s, int off, char *str)
   205  {
   206  	int n;
   207  	Strlit *lit;
   208  
   209  	if(str == nil)
   210  		return duintptr(s, off, 0);
   211  
   212  	n = strlen(str);
   213  	lit = mal(sizeof *lit + n);
   214  	strcpy(lit->s, str);
   215  	lit->len = n;
   216  	return dgostrlitptr(s, off, lit);
   217  }
   218  
   219  int
   220  dsymptr(Sym *s, int off, Sym *x, int xoff)
   221  {
   222  	Prog *p;
   223  
   224  	off = rnd(off, widthptr);
   225  
   226  	p = gins(ADATA, N, N);
   227  	p->from.type = D_EXTERN;
   228  	p->from.index = D_NONE;
   229  	p->from.sym = linksym(s);
   230  	p->from.offset = off;
   231  	p->from.scale = widthptr;
   232  	p->to.type = D_ADDR;
   233  	p->to.index = D_EXTERN;
   234  	p->to.sym = linksym(x);
   235  	p->to.offset = xoff;
   236  	off += widthptr;
   237  
   238  	return off;
   239  }
   240  
   241  void
   242  nopout(Prog *p)
   243  {
   244  	p->as = ANOP;
   245  }
   246