2008-06-04 15:37:38 -06:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
|
|
|
|
|
|
|
#include "../gc/go.h"
|
|
|
|
#include "../6l/6.out.h"
|
|
|
|
|
|
|
|
#ifndef EXTERN
|
|
|
|
#define EXTERN extern
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct Prog Prog;
|
|
|
|
typedef struct Addr Addr;
|
|
|
|
|
|
|
|
struct Addr
|
|
|
|
{
|
|
|
|
vlong offset;
|
|
|
|
double dval;
|
|
|
|
Prog* branch;
|
|
|
|
char sval[NSNAME];
|
|
|
|
|
|
|
|
Sym* sym;
|
|
|
|
uchar type;
|
|
|
|
uchar index;
|
|
|
|
uchar etype;
|
|
|
|
uchar scale; /* doubles as width in DATA op */
|
|
|
|
};
|
|
|
|
#define A ((Addr*)0)
|
|
|
|
|
|
|
|
struct Prog
|
|
|
|
{
|
|
|
|
short as; // opcode
|
2008-08-03 18:25:15 -06:00
|
|
|
uint32 loc; // pc offset in this func
|
|
|
|
uint32 lineno; // source line that generated this
|
2008-06-04 15:37:38 -06:00
|
|
|
Addr from; // src address
|
|
|
|
Addr to; // dst address
|
|
|
|
Prog* link; // next instruction in this func
|
|
|
|
};
|
|
|
|
#define P ((Prog*)0)
|
|
|
|
|
|
|
|
typedef struct Plist Plist;
|
|
|
|
struct Plist
|
|
|
|
{
|
|
|
|
Node* name;
|
|
|
|
Dcl* locals;
|
|
|
|
Prog* firstpc;
|
|
|
|
int recur;
|
|
|
|
Plist* link;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct Sig Sig;
|
|
|
|
struct Sig
|
|
|
|
{
|
|
|
|
char* name;
|
|
|
|
Sym* sym;
|
2008-08-03 18:25:15 -06:00
|
|
|
uint32 hash;
|
2008-10-02 21:51:10 -06:00
|
|
|
int32 perm;
|
2008-08-03 18:25:15 -06:00
|
|
|
int32 offset;
|
2008-06-04 15:37:38 -06:00
|
|
|
Sig* link;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct Case Case;
|
|
|
|
struct Case
|
|
|
|
{
|
|
|
|
Prog* sprog;
|
|
|
|
Node* scase;
|
|
|
|
Case* slink;
|
|
|
|
};
|
|
|
|
#define C ((Case*)0)
|
|
|
|
|
|
|
|
typedef struct Pool Pool;
|
|
|
|
struct Pool
|
|
|
|
{
|
|
|
|
String* sval;
|
|
|
|
Pool* link;
|
|
|
|
};
|
|
|
|
|
2008-08-29 21:30:19 -06:00
|
|
|
typedef struct Label Label;
|
|
|
|
struct Label
|
|
|
|
{
|
|
|
|
uchar op; // OFOR/OGOTO/OLABEL
|
|
|
|
Sym* sym;
|
|
|
|
Prog* label; // pointer to code
|
|
|
|
Prog* breakpc; // pointer to code
|
|
|
|
Prog* continpc; // pointer to code
|
|
|
|
Label* link;
|
|
|
|
};
|
|
|
|
#define L ((Label*)0)
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
EXTERN Prog* continpc;
|
|
|
|
EXTERN Prog* breakpc;
|
|
|
|
EXTERN Prog* pc;
|
|
|
|
EXTERN Prog* firstpc;
|
|
|
|
EXTERN Plist* plist;
|
|
|
|
EXTERN Plist* plast;
|
|
|
|
EXTERN Pool* poolist;
|
|
|
|
EXTERN Pool* poolast;
|
|
|
|
EXTERN Biobuf* bout;
|
2008-08-03 18:25:15 -06:00
|
|
|
EXTERN int32 dynloc;
|
2008-06-04 15:37:38 -06:00
|
|
|
EXTERN uchar reg[D_NONE];
|
|
|
|
EXTERN ushort txt[NTYPE*NTYPE];
|
2008-08-03 18:25:15 -06:00
|
|
|
EXTERN int32 maxround;
|
|
|
|
EXTERN int32 widthptr;
|
2008-06-04 15:37:38 -06:00
|
|
|
EXTERN Sym* symstringo; // string objects
|
2008-08-03 18:25:15 -06:00
|
|
|
EXTERN int32 stringo; // size of string objects
|
|
|
|
EXTERN int32 pcloc; // instruction counter
|
2008-06-04 15:37:38 -06:00
|
|
|
EXTERN String emptystring;
|
|
|
|
extern char* anames[];
|
2008-06-13 19:16:23 -06:00
|
|
|
EXTERN Hist* hist;
|
|
|
|
EXTERN Prog zprog;
|
2008-08-29 21:30:19 -06:00
|
|
|
EXTERN Label* labellist;
|
|
|
|
EXTERN Label* findlab(Sym*);
|
2008-09-12 17:48:35 -06:00
|
|
|
EXTERN Node* curfn;
|
|
|
|
EXTERN Node* newproc;
|
|
|
|
EXTERN Node* throwindex;
|
|
|
|
EXTERN Node* throwreturn;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* gen.c
|
|
|
|
*/
|
|
|
|
void compile(Node*);
|
|
|
|
void proglist(void);
|
2008-08-29 21:30:19 -06:00
|
|
|
void gen(Node*, Label*);
|
2008-06-04 15:37:38 -06:00
|
|
|
void swgen(Node*);
|
2008-07-24 16:57:30 -06:00
|
|
|
void selgen(Node*);
|
2008-06-04 15:37:38 -06:00
|
|
|
Node* lookdot(Node*, Node*, int);
|
|
|
|
void inarggen(void);
|
|
|
|
void cgen_as(Node*, Node*, int);
|
2008-06-12 15:21:09 -06:00
|
|
|
void cgen_asop(Node*);
|
2008-06-04 15:37:38 -06:00
|
|
|
void cgen_ret(Node*);
|
2008-07-07 18:59:32 -06:00
|
|
|
void cgen_call(Node*, int);
|
|
|
|
void cgen_callmeth(Node*, int);
|
|
|
|
void cgen_callinter(Node*, Node*, int);
|
|
|
|
void cgen_proc(Node*);
|
2008-06-04 15:37:38 -06:00
|
|
|
void cgen_callret(Node*, Node*);
|
2008-06-06 21:43:29 -06:00
|
|
|
void cgen_div(int, Node*, Node*, Node*);
|
2008-11-07 15:20:32 -07:00
|
|
|
void cgen_bmul(int, Node*, Node*, Node*);
|
2008-06-07 16:21:02 -06:00
|
|
|
void cgen_shift(int, Node*, Node*, Node*);
|
2008-06-04 15:37:38 -06:00
|
|
|
void genpanic(void);
|
|
|
|
int needconvert(Type*, Type*);
|
|
|
|
void genconv(Type*, Type*);
|
|
|
|
void allocparams(void);
|
2008-08-29 21:30:19 -06:00
|
|
|
void checklabels();
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* cgen
|
|
|
|
*/
|
|
|
|
void cgen(Node*, Node*);
|
|
|
|
void agen(Node*, Node*);
|
|
|
|
void igen(Node*, Node*, Node*);
|
|
|
|
vlong fieldoffset(Type*, Node*);
|
|
|
|
void bgen(Node*, int, Prog*);
|
2008-09-22 17:58:30 -06:00
|
|
|
void sgen(Node*, Node*, int32);
|
2008-06-04 15:37:38 -06:00
|
|
|
void gmove(Node*, Node*);
|
|
|
|
Prog* gins(int, Node*, Node*);
|
|
|
|
int samaddr(Node*, Node*);
|
|
|
|
void naddr(Node*, Addr*);
|
2008-10-03 17:23:02 -06:00
|
|
|
void cgen_aret(Node*, Node*);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* gsubr.c
|
|
|
|
*/
|
|
|
|
void clearp(Prog*);
|
|
|
|
void proglist(void);
|
|
|
|
Prog* gbranch(int, Type*);
|
|
|
|
void patch(Prog*, Prog*);
|
|
|
|
Prog* prog(int);
|
|
|
|
void gaddoffset(Node*);
|
|
|
|
void gconv(int, int);
|
|
|
|
int conv2pt(Type*);
|
|
|
|
void belexinit(int);
|
|
|
|
vlong convvtox(vlong, int);
|
|
|
|
int brcom(int);
|
|
|
|
int brrev(int);
|
|
|
|
void fnparam(Type*, int, int);
|
|
|
|
Sig* lsort(Sig*, int(*)(Sig*, Sig*));
|
|
|
|
Prog* gop(int, Node*, Node*, Node*);
|
|
|
|
void setconst(Addr*, vlong);
|
|
|
|
void setaddr(Addr*, Node*);
|
|
|
|
int optoas(int, Type*);
|
|
|
|
void ginit(void);
|
|
|
|
void gclean(void);
|
|
|
|
void regalloc(Node*, Type*, Node*);
|
|
|
|
void regfree(Node*);
|
|
|
|
void regsalloc(Node*, Type*); // replace w tmpvar
|
|
|
|
void regret(Node*, Type*);
|
|
|
|
Node* nodarg(Type*, int);
|
|
|
|
void nodreg(Node*, Type*, int);
|
|
|
|
void nodindreg(Node*, Type*, int);
|
|
|
|
void nodconst(Node*, Type*, vlong);
|
|
|
|
void gconreg(int, vlong, int);
|
|
|
|
void buildtxt(void);
|
|
|
|
void stringpool(Node*);
|
|
|
|
void tempname(Node*, Type*);
|
|
|
|
Plist* newplist(void);
|
|
|
|
int isfat(Type*);
|
|
|
|
void setmaxarg(Type*);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* list.c
|
|
|
|
*/
|
|
|
|
int Aconv(Fmt*);
|
|
|
|
int Dconv(Fmt*);
|
|
|
|
int Pconv(Fmt*);
|
|
|
|
int Rconv(Fmt*);
|
|
|
|
int Yconv(Fmt*);
|
|
|
|
void listinit(void);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* obj
|
|
|
|
*/
|
|
|
|
void zname(Biobuf*, Sym*, int);
|
|
|
|
void zaddr(Biobuf*, Addr*, int);
|
|
|
|
void ieeedtod(Ieee*, double);
|
|
|
|
void dumpstrings(void);
|
|
|
|
void dumpsignatures(void);
|
2008-06-13 19:16:23 -06:00
|
|
|
void outhist(Biobuf*);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* align
|
|
|
|
*/
|
|
|
|
void dowidth(Type*);
|
2008-08-03 18:25:15 -06:00
|
|
|
uint32 rnd(uint32, uint32);
|