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

     1  // Derived from Inferno utils/6c/swt.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6c/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+widthint;  // skip header
    67  	a->etype = simtype[TINT];
    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  
    92  	if(nr->op == OLITERAL) {
    93  		switch(nr->val.ctype) {
    94  		case CTCPLX:
    95  			gdatacomplex(nam, nr->val.u.cval);
    96  			return;
    97  		case CTSTR:
    98  			gdatastring(nam, nr->val.u.sval);
    99  			return;
   100  		}
   101  	}
   102  	p = gins(ADATA, nam, nr);
   103  	p->from.scale = wid;
   104  }
   105  
   106  void
   107  gdatacomplex(Node *nam, Mpcplx *cval)
   108  {
   109  	Prog *p;
   110  	int w;
   111  
   112  	w = cplxsubtype(nam->type->etype);
   113  	w = types[w]->width;
   114  
   115  	p = gins(ADATA, nam, N);
   116  	p->from.scale = w;
   117  	p->to.type = D_FCONST;
   118  	p->to.u.dval = mpgetflt(&cval->real);
   119  
   120  	p = gins(ADATA, nam, N);
   121  	p->from.scale = w;
   122  	p->from.offset += w;
   123  	p->to.type = D_FCONST;
   124  	p->to.u.dval = mpgetflt(&cval->imag);
   125  }
   126  
   127  void
   128  gdatastring(Node *nam, Strlit *sval)
   129  {
   130  	Prog *p;
   131  	Node nod1;
   132  
   133  	p = gins(ADATA, nam, N);
   134  	datastring(sval->s, sval->len, &p->to);
   135  	p->from.scale = types[tptr]->width;
   136  	p->to.index = p->to.type;
   137  	p->to.type = D_ADDR;
   138  //print("%P\n", p);
   139  
   140  	nodconst(&nod1, types[TINT], sval->len);
   141  	p = gins(ADATA, nam, &nod1);
   142  	p->from.scale = widthint;
   143  	p->from.offset += widthptr;
   144  }
   145  
   146  int
   147  dstringptr(Sym *s, int off, char *str)
   148  {
   149  	Prog *p;
   150  
   151  	off = rnd(off, widthptr);
   152  	p = gins(ADATA, N, N);
   153  	p->from.type = D_EXTERN;
   154  	p->from.index = D_NONE;
   155  	p->from.sym = linksym(s);
   156  	p->from.offset = off;
   157  	p->from.scale = widthptr;
   158  
   159  	datastring(str, strlen(str)+1, &p->to);
   160  	p->to.index = p->to.type;
   161  	p->to.type = D_ADDR;
   162  	p->to.etype = simtype[TINT];
   163  	off += widthptr;
   164  
   165  	return off;
   166  }
   167  
   168  int
   169  dgostrlitptr(Sym *s, int off, Strlit *lit)
   170  {
   171  	Prog *p;
   172  
   173  	if(lit == nil)
   174  		return duintptr(s, off, 0);
   175  
   176  	off = rnd(off, widthptr);
   177  	p = gins(ADATA, N, N);
   178  	p->from.type = D_EXTERN;
   179  	p->from.index = D_NONE;
   180  	p->from.sym = linksym(s);
   181  	p->from.offset = off;
   182  	p->from.scale = widthptr;
   183  	datagostring(lit, &p->to);
   184  	p->to.index = p->to.type;
   185  	p->to.type = D_ADDR;
   186  	p->to.etype = simtype[TINT];
   187  	off += widthptr;
   188  
   189  	return off;
   190  }
   191  
   192  int
   193  dgostringptr(Sym *s, int off, char *str)
   194  {
   195  	int n;
   196  	Strlit *lit;
   197  
   198  	if(str == nil)
   199  		return duintptr(s, off, 0);
   200  
   201  	n = strlen(str);
   202  	lit = mal(sizeof *lit + n);
   203  	strcpy(lit->s, str);
   204  	lit->len = n;
   205  	return dgostrlitptr(s, off, lit);
   206  }
   207  
   208  int
   209  dsymptr(Sym *s, int off, Sym *x, int xoff)
   210  {
   211  	Prog *p;
   212  
   213  	off = rnd(off, widthptr);
   214  
   215  	p = gins(ADATA, N, N);
   216  	p->from.type = D_EXTERN;
   217  	p->from.index = D_NONE;
   218  	p->from.sym = linksym(s);
   219  	p->from.offset = off;
   220  	p->from.scale = widthptr;
   221  	p->to.type = D_ADDR;
   222  	p->to.index = D_EXTERN;
   223  	p->to.sym = linksym(x);
   224  	p->to.offset = xoff;
   225  	off += widthptr;
   226  
   227  	return off;
   228  }
   229  
   230  void
   231  nopout(Prog *p)
   232  {
   233  	p->as = ANOP;
   234  }
   235