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 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
|
2008-11-18 20:24:37 -07:00
|
|
|
void* reg; // pointer to containing Reg struct
|
2008-06-04 15:37:38 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
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];
|
2008-08-03 18:25:15 -06:00
|
|
|
EXTERN int32 pcloc; // instruction counter
|
2009-04-09 19:16:21 -06:00
|
|
|
EXTERN Strlit emptystring;
|
2008-06-04 15:37:38 -06:00
|
|
|
extern char* anames[];
|
2008-06-13 19:16:23 -06:00
|
|
|
EXTERN Hist* hist;
|
|
|
|
EXTERN Prog zprog;
|
2008-09-12 17:48:35 -06:00
|
|
|
EXTERN Node* curfn;
|
|
|
|
EXTERN Node* newproc;
|
2009-01-27 13:03:53 -07:00
|
|
|
EXTERN Node* deferproc;
|
|
|
|
EXTERN Node* deferreturn;
|
2008-09-12 17:48:35 -06:00
|
|
|
EXTERN Node* throwindex;
|
|
|
|
EXTERN Node* throwreturn;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* gen.c
|
|
|
|
*/
|
|
|
|
void compile(Node*);
|
|
|
|
void proglist(void);
|
2009-03-11 17:25:45 -06:00
|
|
|
void gen(Node*);
|
2008-06-04 15:37:38 -06:00
|
|
|
Node* lookdot(Node*, Node*, int);
|
2009-01-05 18:32:23 -07:00
|
|
|
void cgen_as(Node*, Node*);
|
2008-07-07 18:59:32 -06:00
|
|
|
void cgen_callmeth(Node*, int);
|
|
|
|
void cgen_callinter(Node*, Node*, int);
|
2009-01-27 13:03:53 -07:00
|
|
|
void cgen_proc(Node*, int);
|
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*);
|
2009-01-29 18:38:58 -07:00
|
|
|
void cgen_dcl(Node*);
|
2008-06-04 15:37:38 -06:00
|
|
|
int needconvert(Type*, Type*);
|
|
|
|
void genconv(Type*, Type*);
|
|
|
|
void allocparams(void);
|
2008-08-29 21:30:19 -06:00
|
|
|
void checklabels();
|
2009-01-30 15:39:42 -07:00
|
|
|
void ginscall(Node*, int);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* cgen
|
|
|
|
*/
|
|
|
|
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*);
|
|
|
|
Prog* prog(int);
|
|
|
|
void gaddoffset(Node*);
|
|
|
|
void gconv(int, int);
|
|
|
|
int conv2pt(Type*);
|
|
|
|
vlong convvtox(vlong, int);
|
|
|
|
void fnparam(Type*, int, int);
|
|
|
|
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*);
|
|
|
|
Node* nodarg(Type*, int);
|
|
|
|
void nodreg(Node*, Type*, int);
|
|
|
|
void nodindreg(Node*, Type*, int);
|
|
|
|
void gconreg(int, vlong, int);
|
|
|
|
void buildtxt(void);
|
|
|
|
Plist* newplist(void);
|
|
|
|
int isfat(Type*);
|
2008-12-14 18:06:06 -07:00
|
|
|
void sudoclean(void);
|
2009-05-03 16:17:03 -06:00
|
|
|
int sudoaddable(int, Node*, Addr*);
|
2009-01-30 15:39:42 -07:00
|
|
|
void afunclit(Addr*);
|
2009-05-06 14:47:40 -06:00
|
|
|
void datagostring(Strlit*, Addr*);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* list.c
|
|
|
|
*/
|
|
|
|
int Aconv(Fmt*);
|
|
|
|
int Dconv(Fmt*);
|
|
|
|
int Pconv(Fmt*);
|
|
|
|
int Rconv(Fmt*);
|
|
|
|
int Yconv(Fmt*);
|
|
|
|
void listinit(void);
|
|
|
|
|
|
|
|
void zaddr(Biobuf*, Addr*, int);
|
|
|
|
|