github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/src/cmd/5g/gobj.c (about)

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