add arm64 c compiler and assembler (thanks charles forsyth)
this is the the initial sync of charles forsyths plan9 c compiler suite from http://bitbucket.org/plan9-from-bell-labs/9-cc at changeset version 54:65fb8bb56c59
This commit is contained in:
parent
e897df33e6
commit
b29d5ac7b1
17 changed files with 10348 additions and 0 deletions
185
sys/src/cmd/7a/a.h
Normal file
185
sys/src/cmd/7a/a.h
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* arm64
|
||||||
|
*/
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <bio.h>
|
||||||
|
#include "../7c/7.out.h"
|
||||||
|
|
||||||
|
typedef vlong int64;
|
||||||
|
|
||||||
|
#ifndef EXTERN
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct Sym Sym;
|
||||||
|
typedef struct Gen Gen;
|
||||||
|
typedef struct Io Io;
|
||||||
|
typedef struct Hist Hist;
|
||||||
|
|
||||||
|
#define MAXALIGN 7
|
||||||
|
#define FPCHIP 1
|
||||||
|
#define NSYMB 8192
|
||||||
|
#define BUFSIZ 8192
|
||||||
|
#define HISTSZ 20
|
||||||
|
#define NINCLUDE 10
|
||||||
|
#define NHUNK 10000
|
||||||
|
#define EOF (-1)
|
||||||
|
#define IGN (-2)
|
||||||
|
#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
|
||||||
|
#define NHASH 503
|
||||||
|
#define STRINGSZ 200
|
||||||
|
#define NMACRO 10
|
||||||
|
|
||||||
|
struct Sym
|
||||||
|
{
|
||||||
|
Sym* link;
|
||||||
|
char* macro;
|
||||||
|
long value;
|
||||||
|
ushort type;
|
||||||
|
char *name;
|
||||||
|
char sym;
|
||||||
|
};
|
||||||
|
#define S ((Sym*)0)
|
||||||
|
|
||||||
|
EXTERN struct
|
||||||
|
{
|
||||||
|
char* p;
|
||||||
|
int c;
|
||||||
|
} fi;
|
||||||
|
|
||||||
|
struct Io
|
||||||
|
{
|
||||||
|
Io* link;
|
||||||
|
char b[BUFSIZ];
|
||||||
|
char* p;
|
||||||
|
short c;
|
||||||
|
short f;
|
||||||
|
};
|
||||||
|
#define I ((Io*)0)
|
||||||
|
|
||||||
|
EXTERN struct
|
||||||
|
{
|
||||||
|
Sym* sym;
|
||||||
|
short type;
|
||||||
|
} h[NSYM];
|
||||||
|
|
||||||
|
struct Gen
|
||||||
|
{
|
||||||
|
Sym* sym;
|
||||||
|
int64 offset;
|
||||||
|
short type;
|
||||||
|
short reg;
|
||||||
|
short xreg;
|
||||||
|
short name;
|
||||||
|
short ext;
|
||||||
|
double dval;
|
||||||
|
char sval[NSNAME];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Hist
|
||||||
|
{
|
||||||
|
Hist* link;
|
||||||
|
char* name;
|
||||||
|
long line;
|
||||||
|
long offset;
|
||||||
|
};
|
||||||
|
#define H ((Hist*)0)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CLAST,
|
||||||
|
CMACARG,
|
||||||
|
CMACRO,
|
||||||
|
CPREPROC,
|
||||||
|
};
|
||||||
|
|
||||||
|
EXTERN char debug[256];
|
||||||
|
EXTERN Sym* hash[NHASH];
|
||||||
|
EXTERN char* Dlist[30];
|
||||||
|
EXTERN int nDlist;
|
||||||
|
EXTERN Hist* ehist;
|
||||||
|
EXTERN int newflag;
|
||||||
|
EXTERN Hist* hist;
|
||||||
|
EXTERN char* hunk;
|
||||||
|
EXTERN char* include[NINCLUDE];
|
||||||
|
EXTERN Io* iofree;
|
||||||
|
EXTERN Io* ionext;
|
||||||
|
EXTERN Io* iostack;
|
||||||
|
EXTERN long lineno;
|
||||||
|
EXTERN int nerrors;
|
||||||
|
EXTERN long nhunk;
|
||||||
|
EXTERN int ninclude;
|
||||||
|
EXTERN Gen nullgen;
|
||||||
|
EXTERN char* outfile;
|
||||||
|
EXTERN int pass;
|
||||||
|
EXTERN char* pathname;
|
||||||
|
EXTERN long pc;
|
||||||
|
EXTERN int peekc;
|
||||||
|
EXTERN int sym;
|
||||||
|
EXTERN char symb[NSYMB];
|
||||||
|
EXTERN int thechar;
|
||||||
|
EXTERN char* thestring;
|
||||||
|
EXTERN long thunk;
|
||||||
|
EXTERN Biobuf obuf;
|
||||||
|
|
||||||
|
void* alloc(long);
|
||||||
|
void* allocn(void*, long, long);
|
||||||
|
void errorexit(void);
|
||||||
|
void pushio(void);
|
||||||
|
void newio(void);
|
||||||
|
void newfile(char*, int);
|
||||||
|
Sym* slookup(char*);
|
||||||
|
Sym* lookup(void);
|
||||||
|
void syminit(Sym*);
|
||||||
|
long yylex(void);
|
||||||
|
int getc(void);
|
||||||
|
int getnsc(void);
|
||||||
|
void unget(int);
|
||||||
|
int escchar(int);
|
||||||
|
void cinit(void);
|
||||||
|
void pinit(char*);
|
||||||
|
void cclean(void);
|
||||||
|
void outcode(int, Gen*, int, Gen*);
|
||||||
|
void outcodec(int, int, Gen*, int, Gen*);
|
||||||
|
void outcode4(int, Gen*, int, Gen*, Gen*);
|
||||||
|
void zname(char*, int, int);
|
||||||
|
void zaddr(Gen*, int);
|
||||||
|
void ieeedtod(Ieee*, double);
|
||||||
|
int filbuf(void);
|
||||||
|
Sym* getsym(void);
|
||||||
|
void domacro(void);
|
||||||
|
void macund(void);
|
||||||
|
void macdef(void);
|
||||||
|
void macexpand(Sym*, char*);
|
||||||
|
void macinc(void);
|
||||||
|
void maclin(void);
|
||||||
|
void macprag(void);
|
||||||
|
void macif(int);
|
||||||
|
void macend(void);
|
||||||
|
void outhist(void);
|
||||||
|
void dodefine(char*);
|
||||||
|
void prfile(long);
|
||||||
|
void linehist(char*, int);
|
||||||
|
void gethunk(void);
|
||||||
|
void yyerror(char*, ...);
|
||||||
|
int yyparse(void);
|
||||||
|
void setinclude(char*);
|
||||||
|
int assemble(char*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* system-dependent stuff from ../cc/compat.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum /* keep in synch with ../cc/cc.h */
|
||||||
|
{
|
||||||
|
Plan9 = 1<<0,
|
||||||
|
Unix = 1<<1,
|
||||||
|
Windows = 1<<2,
|
||||||
|
};
|
||||||
|
int mywait(int*);
|
||||||
|
int mycreat(char*, int);
|
||||||
|
int systemtype(int);
|
||||||
|
int pathchar(void);
|
||||||
|
int myfork(void);
|
||||||
|
void* mysbrk(ulong);
|
878
sys/src/cmd/7a/a.y
Normal file
878
sys/src/cmd/7a/a.y
Normal file
|
@ -0,0 +1,878 @@
|
||||||
|
%{
|
||||||
|
#include "a.h"
|
||||||
|
%}
|
||||||
|
%union
|
||||||
|
{
|
||||||
|
Sym *sym;
|
||||||
|
vlong lval;
|
||||||
|
double dval;
|
||||||
|
char sval[NSNAME];
|
||||||
|
Gen gen;
|
||||||
|
}
|
||||||
|
%left '|'
|
||||||
|
%left '^'
|
||||||
|
%left '&'
|
||||||
|
%left '<' '>'
|
||||||
|
%left '+' '-'
|
||||||
|
%left '*' '/' '%'
|
||||||
|
%token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
|
||||||
|
%token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
|
||||||
|
%token <lval> LTYPEB LTYPEC LTYPED LTYPEE LTYPEF
|
||||||
|
%token <lval> LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
|
||||||
|
%token <lval> LTYPEL LTYPEM LTYPEN LTYPEO LTYPEP LTYPEQ
|
||||||
|
%token <lval> LTYPER LTYPES LTYPET LTYPEU LTYPEV LTYPEW LTYPEX LTYPEY LTYPEZ
|
||||||
|
%token <lval> LMOVK LDMB LSTXR
|
||||||
|
%token <lval> LCONST LSP LSB LFP LPC
|
||||||
|
%token <lval> LR LREG LF LFREG LV LVREG LC LCREG LFCR LFCSEL
|
||||||
|
%token <lval> LCOND LS LAT LEXT LSPR LSPREG LVTYPE
|
||||||
|
%token <dval> LFCONST
|
||||||
|
%token <sval> LSCONST
|
||||||
|
%token <sym> LNAME LLAB LVAR
|
||||||
|
%type <lval> con expr pointer offset sreg spreg
|
||||||
|
%type <lval> scon indexreg vset vreglist
|
||||||
|
%type <gen> gen rel reg freg vreg shift fcon frcon extreg vlane vgen
|
||||||
|
%type <gen> imm ximm name oreg nireg ioreg imsr spr cond sysarg
|
||||||
|
%%
|
||||||
|
prog:
|
||||||
|
| prog line
|
||||||
|
|
||||||
|
line:
|
||||||
|
LLAB ':'
|
||||||
|
{
|
||||||
|
if($1->value != pc)
|
||||||
|
yyerror("redeclaration of %s", $1->name);
|
||||||
|
$1->value = pc;
|
||||||
|
}
|
||||||
|
line
|
||||||
|
| LNAME ':'
|
||||||
|
{
|
||||||
|
$1->type = LLAB;
|
||||||
|
$1->value = pc;
|
||||||
|
}
|
||||||
|
line
|
||||||
|
| LNAME '=' expr ';'
|
||||||
|
{
|
||||||
|
$1->type = LVAR;
|
||||||
|
$1->value = $3;
|
||||||
|
}
|
||||||
|
| LVAR '=' expr ';'
|
||||||
|
{
|
||||||
|
if($1->value != $3)
|
||||||
|
yyerror("redeclaration of %s", $1->name);
|
||||||
|
$1->value = $3;
|
||||||
|
}
|
||||||
|
| ';'
|
||||||
|
| inst ';'
|
||||||
|
| error ';'
|
||||||
|
|
||||||
|
inst:
|
||||||
|
/*
|
||||||
|
* ERET
|
||||||
|
*/
|
||||||
|
LTYPE0 comma
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* ADD
|
||||||
|
*/
|
||||||
|
| LTYPE1 imsr ',' spreg ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4, &$6);
|
||||||
|
}
|
||||||
|
| LTYPE1 imsr ',' spreg ','
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4, &nullgen);
|
||||||
|
}
|
||||||
|
| LTYPE1 imsr ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* CLS
|
||||||
|
*/
|
||||||
|
| LTYPE2 imsr ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* MOV
|
||||||
|
*/
|
||||||
|
| LTYPE3 gen ',' gen
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* MOVK
|
||||||
|
*/
|
||||||
|
| LMOVK imm ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
| LMOVK imm '<' '<' con ',' reg
|
||||||
|
{
|
||||||
|
Gen g;
|
||||||
|
g = nullgen;
|
||||||
|
g.type = D_CONST;
|
||||||
|
g.offset = $5;
|
||||||
|
outcode4($1, &$2, NREG, &g, &$7);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* B/BL
|
||||||
|
*/
|
||||||
|
| LTYPE4 comma rel
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &$3);
|
||||||
|
}
|
||||||
|
| LTYPE4 comma nireg
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &$3);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* BEQ
|
||||||
|
*/
|
||||||
|
| LTYPE5 comma rel
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &$3);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* SVC
|
||||||
|
*/
|
||||||
|
| LTYPE6 comma gen
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &$3);
|
||||||
|
}
|
||||||
|
| LTYPE6
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* CMP
|
||||||
|
*/
|
||||||
|
| LTYPE7 imsr ',' spreg comma
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4, &nullgen);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* CBZ
|
||||||
|
*/
|
||||||
|
| LTYPE8 reg ',' rel
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* CSET
|
||||||
|
*/
|
||||||
|
| LTYPER cond ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* CSEL/CINC/CNEG/CINV
|
||||||
|
*/
|
||||||
|
| LTYPES cond ',' reg ',' reg ',' reg
|
||||||
|
{
|
||||||
|
outcode4($1, &$2, $6.reg, &$4, &$8);
|
||||||
|
}
|
||||||
|
| LTYPES cond ',' reg ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4.reg, &$6);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* TBZ
|
||||||
|
*/
|
||||||
|
| LTYPET imm ',' reg ',' rel
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4.reg, &$6);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* CCMN
|
||||||
|
*/
|
||||||
|
| LTYPEU cond ',' imsr ',' reg ',' imm comma
|
||||||
|
{
|
||||||
|
outcode4($1, &$2, $6.reg, &$4, &$8);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* ADR
|
||||||
|
*/
|
||||||
|
| LTYPEV rel ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
| LTYPEV '$' name ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$3, NREG, &$5);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* BFM/BFI
|
||||||
|
*/
|
||||||
|
| LTYPEY imm ',' imm ',' spreg ',' reg
|
||||||
|
{
|
||||||
|
outcode4($1, &$2, $6, &$4, &$8);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* EXTR
|
||||||
|
*/
|
||||||
|
| LTYPEP imm ',' reg ',' spreg ',' reg
|
||||||
|
{
|
||||||
|
outcode4($1, &$2, $6, &$4, &$8);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* RET/RETURN
|
||||||
|
*/
|
||||||
|
| LTYPEA comma
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
| LTYPEA reg
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &$2);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* NOP
|
||||||
|
*/
|
||||||
|
| LTYPEQ comma
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
| LTYPEQ reg comma
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
| LTYPEQ freg comma
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
| LTYPEQ ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &$3);
|
||||||
|
}
|
||||||
|
| LTYPEQ ',' freg
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &$3);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* TEXT/GLOBL
|
||||||
|
*/
|
||||||
|
| LTYPEB name ',' imm
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
| LTYPEB name ',' con ',' imm
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4, &$6);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* DATA
|
||||||
|
*/
|
||||||
|
| LTYPEC name '/' con ',' ximm
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4, &$6);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* CASE
|
||||||
|
*/
|
||||||
|
| LTYPED reg ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* word
|
||||||
|
*/
|
||||||
|
| LTYPEH comma ximm
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &$3);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* floating-point
|
||||||
|
*/
|
||||||
|
| LTYPEI freg ',' freg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* FADDD
|
||||||
|
*/
|
||||||
|
| LTYPEK frcon ',' freg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
| LTYPEK frcon ',' freg ',' freg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4.reg, &$6);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* FCMP
|
||||||
|
*/
|
||||||
|
| LTYPEL frcon ',' freg comma
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4.reg, &nullgen);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* FCCMP
|
||||||
|
*/
|
||||||
|
| LTYPEF cond ',' freg ',' freg ',' imm comma
|
||||||
|
{
|
||||||
|
outcode4($1, &$2, $6.reg, &$4, &$8);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* FMULA
|
||||||
|
*/
|
||||||
|
| LTYPE9 freg ',' freg ', ' freg ',' freg comma
|
||||||
|
{
|
||||||
|
outcode4($1, &$2, $4.reg, &$6, &$8);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* FCSEL
|
||||||
|
*/
|
||||||
|
| LFCSEL cond ',' freg ',' freg ',' freg
|
||||||
|
{
|
||||||
|
outcode4($1, &$2, $6.reg, &$4, &$8);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* SIMD
|
||||||
|
*/
|
||||||
|
| LTYPEW vgen ',' vgen
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
| LTYPEW vgen ',' vgen ',' vgen
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4.reg, &$6);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* MOVP/MOVNP
|
||||||
|
*/
|
||||||
|
| LTYPEJ gen ',' sreg ',' gen
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $4, &$6);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* MADD Rn,Rm,Ra,Rd
|
||||||
|
*/
|
||||||
|
| LTYPEM reg ',' reg ',' sreg ',' reg
|
||||||
|
{
|
||||||
|
outcode4($1, &$2, $6, &$4, &$8);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* SYS/SYSL
|
||||||
|
*/
|
||||||
|
| LTYPEN sysarg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
| LTYPEN reg ',' sysarg
|
||||||
|
{
|
||||||
|
outcode($1, &$4, $2.reg, &nullgen);
|
||||||
|
}
|
||||||
|
| LTYPEO sysarg ',' reg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* DMB, HINT
|
||||||
|
*/
|
||||||
|
| LDMB imm
|
||||||
|
{
|
||||||
|
outcode($1, &$2, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* STXR
|
||||||
|
*/
|
||||||
|
| LSTXR reg ',' gen ',' sreg
|
||||||
|
{
|
||||||
|
outcode($1, &$2, $6, &$4);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* END
|
||||||
|
*/
|
||||||
|
| LTYPEE comma
|
||||||
|
{
|
||||||
|
outcode($1, &nullgen, NREG, &nullgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
cond:
|
||||||
|
LCOND
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_COND;
|
||||||
|
$$.reg = $1;
|
||||||
|
}
|
||||||
|
|
||||||
|
comma:
|
||||||
|
| ',' comma
|
||||||
|
|
||||||
|
sysarg:
|
||||||
|
con ',' con ',' con ',' con
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_CONST;
|
||||||
|
$$.offset = SYSARG4($1, $3, $5, $7);
|
||||||
|
}
|
||||||
|
| imm
|
||||||
|
|
||||||
|
rel:
|
||||||
|
con '(' LPC ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_BRANCH;
|
||||||
|
$$.offset = $1 + pc;
|
||||||
|
}
|
||||||
|
| LNAME offset
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
if(pass == 2)
|
||||||
|
yyerror("undefined label: %s", $1->name);
|
||||||
|
$$.type = D_BRANCH;
|
||||||
|
$$.sym = $1;
|
||||||
|
$$.offset = $2;
|
||||||
|
}
|
||||||
|
| LLAB offset
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_BRANCH;
|
||||||
|
$$.sym = $1;
|
||||||
|
$$.offset = $1->value + $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ximm: '$' con
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_CONST;
|
||||||
|
$$.offset = $2;
|
||||||
|
}
|
||||||
|
| '$' oreg
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
$$.type = D_CONST;
|
||||||
|
}
|
||||||
|
| '$' '*' '$' oreg
|
||||||
|
{
|
||||||
|
$$ = $4;
|
||||||
|
$$.type = D_OCONST;
|
||||||
|
}
|
||||||
|
| '$' LSCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_SCONST;
|
||||||
|
memmove($$.sval, $2, sizeof($$.sval));
|
||||||
|
}
|
||||||
|
| fcon
|
||||||
|
|
||||||
|
fcon:
|
||||||
|
'$' LFCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_FCONST;
|
||||||
|
$$.dval = $2;
|
||||||
|
}
|
||||||
|
| '$' '-' LFCONST
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_FCONST;
|
||||||
|
$$.dval = -$3;
|
||||||
|
}
|
||||||
|
|
||||||
|
gen:
|
||||||
|
reg
|
||||||
|
| ximm
|
||||||
|
| LFCR
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_SPR;
|
||||||
|
$$.offset = $1;
|
||||||
|
}
|
||||||
|
| con
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_OREG;
|
||||||
|
$$.offset = $1;
|
||||||
|
}
|
||||||
|
| oreg
|
||||||
|
| freg
|
||||||
|
| vreg
|
||||||
|
| spr
|
||||||
|
|
||||||
|
nireg:
|
||||||
|
'(' sreg ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_OREG;
|
||||||
|
$$.reg = $2;
|
||||||
|
$$.offset = 0;
|
||||||
|
}
|
||||||
|
| name
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
if($1.name != D_EXTERN && $1.name != D_STATIC) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oreg:
|
||||||
|
name
|
||||||
|
| name '(' sreg ')'
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
$$.type = D_OREG;
|
||||||
|
$$.reg = $3;
|
||||||
|
}
|
||||||
|
| ioreg
|
||||||
|
|
||||||
|
ioreg:
|
||||||
|
'(' sreg ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_OREG;
|
||||||
|
$$.reg = $2;
|
||||||
|
$$.offset = 0;
|
||||||
|
}
|
||||||
|
| con '(' sreg ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_OREG;
|
||||||
|
$$.reg = $3;
|
||||||
|
$$.offset = $1;
|
||||||
|
}
|
||||||
|
| con '(' sreg ')' '!'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_XPRE;
|
||||||
|
$$.reg = $3;
|
||||||
|
$$.offset = $1;
|
||||||
|
}
|
||||||
|
| '(' sreg ')' con '!'
|
||||||
|
{
|
||||||
|
$$.type = D_XPOST;
|
||||||
|
$$.offset = $2;
|
||||||
|
}
|
||||||
|
| '(' sreg ')' '(' indexreg ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_ROFF;
|
||||||
|
$$.reg = $2;
|
||||||
|
$$.xreg = $5 & 0x1f;
|
||||||
|
$$.offset = $5;
|
||||||
|
}
|
||||||
|
| '(' sreg ')' '[' indexreg ']'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_ROFF;
|
||||||
|
$$.reg = $2;
|
||||||
|
$$.xreg = $5 & 0x1f;
|
||||||
|
$$.offset = $5 | (1<<16);
|
||||||
|
}
|
||||||
|
|
||||||
|
imsr:
|
||||||
|
imm
|
||||||
|
| shift
|
||||||
|
| extreg
|
||||||
|
|
||||||
|
imm: '$' con
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_CONST;
|
||||||
|
$$.offset = $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg:
|
||||||
|
sreg
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_REG;
|
||||||
|
$$.reg = $1;
|
||||||
|
}
|
||||||
|
| LSP
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_SP;
|
||||||
|
$$.reg = REGSP;
|
||||||
|
}
|
||||||
|
|
||||||
|
shift:
|
||||||
|
sreg '<' '<' scon
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_SHIFT;
|
||||||
|
$$.offset = ($1 << 16) | ($4 << 10) | (0 << 22);
|
||||||
|
}
|
||||||
|
| sreg '>' '>' scon
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_SHIFT;
|
||||||
|
$$.offset = (($1&0x1F) << 16) | ($4 << 10) | (1 << 22);
|
||||||
|
}
|
||||||
|
| sreg '-' '>' scon
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_SHIFT;
|
||||||
|
$$.offset = ($1 << 16) | ($4 << 10) | (2 << 22);
|
||||||
|
}
|
||||||
|
| sreg LAT '>' scon
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_SHIFT;
|
||||||
|
$$.offset = ($1 << 16) | ($4 << 10) | (3 << 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
extreg:
|
||||||
|
sreg
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_REG;
|
||||||
|
$$.reg = $1;
|
||||||
|
}
|
||||||
|
| sreg LEXT
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_EXTREG;
|
||||||
|
$$.reg = $1;
|
||||||
|
$$.offset = ($1 << 16) | ($2 << 13);
|
||||||
|
}
|
||||||
|
| sreg LEXT '<' '<' con
|
||||||
|
{
|
||||||
|
if($5 < 0 || $5 > 4)
|
||||||
|
yyerror("shift value out of range");
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_EXTREG;
|
||||||
|
$$.reg = $1;
|
||||||
|
$$.offset = ($1 << 16) | ($2 << 13) | ($5 << 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
indexreg:
|
||||||
|
sreg
|
||||||
|
{
|
||||||
|
$$ = (3 << 8) | $1;
|
||||||
|
}
|
||||||
|
| sreg LEXT
|
||||||
|
{
|
||||||
|
$$ = ($2 << 8) | $1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scon:
|
||||||
|
con
|
||||||
|
{
|
||||||
|
if($$ < 0 || $$ >= 64)
|
||||||
|
yyerror("shift value out of range");
|
||||||
|
$$ = $1&0x3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
sreg:
|
||||||
|
LREG
|
||||||
|
| LR '(' expr ')'
|
||||||
|
{
|
||||||
|
if($3 < 0 || $3 >= NREG)
|
||||||
|
print("register value out of range\n");
|
||||||
|
$$ = $3;
|
||||||
|
}
|
||||||
|
|
||||||
|
spreg:
|
||||||
|
sreg
|
||||||
|
| LSP
|
||||||
|
{
|
||||||
|
$$ = REGSP;
|
||||||
|
}
|
||||||
|
|
||||||
|
spr:
|
||||||
|
LSPREG
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_SPR;
|
||||||
|
$$.offset = $1;
|
||||||
|
}
|
||||||
|
| LSPR '(' con ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = $1;
|
||||||
|
$$.offset = $3;
|
||||||
|
}
|
||||||
|
|
||||||
|
frcon:
|
||||||
|
freg
|
||||||
|
| fcon
|
||||||
|
|
||||||
|
freg:
|
||||||
|
LFREG
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_FREG;
|
||||||
|
$$.reg = $1;
|
||||||
|
}
|
||||||
|
| LF '(' con ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_FREG;
|
||||||
|
$$.reg = $3;
|
||||||
|
}
|
||||||
|
|
||||||
|
vgen:
|
||||||
|
oreg
|
||||||
|
| vreg
|
||||||
|
| vlane
|
||||||
|
| vset
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_VSET;
|
||||||
|
$$.offset = $1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlane:
|
||||||
|
vreg '[' con ']'
|
||||||
|
{
|
||||||
|
$$.type = D_VLANE;
|
||||||
|
$$.offset = $3;
|
||||||
|
}
|
||||||
|
| vset '[' con ']'
|
||||||
|
{
|
||||||
|
$$.type = D_VLANE;
|
||||||
|
$$.offset = $3;
|
||||||
|
}
|
||||||
|
|
||||||
|
vset:
|
||||||
|
'{' vreglist '}'
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
vreglist:
|
||||||
|
vreg
|
||||||
|
{
|
||||||
|
$$ = 1 << $1.reg;
|
||||||
|
}
|
||||||
|
| vreg '-' vreg
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
$$=0;
|
||||||
|
for(i=$1.reg; i<=$3.reg; i++)
|
||||||
|
$$ |= 1<<i;
|
||||||
|
for(i=$3.reg; i<=$1.reg; i++)
|
||||||
|
$$ |= 1<<i;
|
||||||
|
}
|
||||||
|
| vreg comma vreglist
|
||||||
|
{
|
||||||
|
$$ = (1<<$1.reg) | $3;
|
||||||
|
}
|
||||||
|
|
||||||
|
vreg:
|
||||||
|
LVREG
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_VREG;
|
||||||
|
$$.reg = $1;
|
||||||
|
/* TO DO: slice */
|
||||||
|
}
|
||||||
|
| LV '(' con ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_VREG;
|
||||||
|
$$.reg = $3;
|
||||||
|
}
|
||||||
|
|
||||||
|
name:
|
||||||
|
con '(' pointer ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_OREG;
|
||||||
|
$$.name = $3;
|
||||||
|
$$.sym = S;
|
||||||
|
$$.offset = $1;
|
||||||
|
}
|
||||||
|
| LNAME offset '(' pointer ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_OREG;
|
||||||
|
$$.name = $4;
|
||||||
|
$$.sym = $1;
|
||||||
|
$$.offset = $2;
|
||||||
|
}
|
||||||
|
| LNAME '<' '>' offset '(' LSB ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_OREG;
|
||||||
|
$$.name = D_STATIC;
|
||||||
|
$$.sym = $1;
|
||||||
|
$$.offset = $4;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset:
|
||||||
|
{
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| '+' con
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
|
| '-' con
|
||||||
|
{
|
||||||
|
$$ = -$2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer:
|
||||||
|
LSB
|
||||||
|
| LSP
|
||||||
|
| LFP
|
||||||
|
|
||||||
|
con:
|
||||||
|
LCONST
|
||||||
|
| LVAR
|
||||||
|
{
|
||||||
|
$$ = $1->value;
|
||||||
|
}
|
||||||
|
| '-' con
|
||||||
|
{
|
||||||
|
$$ = -$2;
|
||||||
|
}
|
||||||
|
| '+' con
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
|
| '~' con
|
||||||
|
{
|
||||||
|
$$ = ~$2;
|
||||||
|
}
|
||||||
|
| '(' expr ')'
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr:
|
||||||
|
con
|
||||||
|
| expr '+' expr
|
||||||
|
{
|
||||||
|
$$ = $1 + $3;
|
||||||
|
}
|
||||||
|
| expr '-' expr
|
||||||
|
{
|
||||||
|
$$ = $1 - $3;
|
||||||
|
}
|
||||||
|
| expr '*' expr
|
||||||
|
{
|
||||||
|
$$ = $1 * $3;
|
||||||
|
}
|
||||||
|
| expr '/' expr
|
||||||
|
{
|
||||||
|
$$ = $1 / $3;
|
||||||
|
}
|
||||||
|
| expr '%' expr
|
||||||
|
{
|
||||||
|
$$ = $1 % $3;
|
||||||
|
}
|
||||||
|
| expr '<' '<' expr
|
||||||
|
{
|
||||||
|
$$ = $1 << $4;
|
||||||
|
}
|
||||||
|
| expr '>' '>' expr
|
||||||
|
{
|
||||||
|
$$ = $1 >> $4;
|
||||||
|
}
|
||||||
|
| expr '&' expr
|
||||||
|
{
|
||||||
|
$$ = $1 & $3;
|
||||||
|
}
|
||||||
|
| expr '^' expr
|
||||||
|
{
|
||||||
|
$$ = $1 ^ $3;
|
||||||
|
}
|
||||||
|
| expr '|' expr
|
||||||
|
{
|
||||||
|
$$ = $1 | $3;
|
||||||
|
}
|
1041
sys/src/cmd/7a/lex.c
Normal file
1041
sys/src/cmd/7a/lex.c
Normal file
File diff suppressed because it is too large
Load diff
19
sys/src/cmd/7a/mkfile
Normal file
19
sys/src/cmd/7a/mkfile
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
</$objtype/mkfile
|
||||||
|
|
||||||
|
TARG=7a
|
||||||
|
OFILES=\
|
||||||
|
y.tab.$O\
|
||||||
|
lex.$O\
|
||||||
|
|
||||||
|
HFILES=\
|
||||||
|
../7c/7.out.h\
|
||||||
|
y.tab.h\
|
||||||
|
a.h\
|
||||||
|
|
||||||
|
YFILES=a.y\
|
||||||
|
|
||||||
|
BIN=/$objtype/bin
|
||||||
|
< /sys/src/cmd/mkone
|
||||||
|
YFLAGS=-D1 -d
|
||||||
|
|
||||||
|
lex.$O: ../cc/macbody ../cc/lexbody
|
517
sys/src/cmd/7c/7.out.h
Normal file
517
sys/src/cmd/7c/7.out.h
Normal file
|
@ -0,0 +1,517 @@
|
||||||
|
/*
|
||||||
|
* arm64
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NSNAME 8
|
||||||
|
#define NSYM 50
|
||||||
|
#define NREG 32
|
||||||
|
|
||||||
|
#define NOPROF (1<<0)
|
||||||
|
#define DUPOK (1<<1)
|
||||||
|
|
||||||
|
#define REGRET 0
|
||||||
|
#define REGARG 0
|
||||||
|
/* R1 to R7 are potential parameter/return registers */
|
||||||
|
#define REGIRL 8 /* indirect result location (TO DO) */
|
||||||
|
/* compiler allocates R9 up as temps */
|
||||||
|
/* compiler allocates register variables R10 up */
|
||||||
|
#define REGMIN 9
|
||||||
|
#define REGMAX 15
|
||||||
|
#define REGIP0 16
|
||||||
|
#define REGIP1 17
|
||||||
|
#define REGTMP REGIP1
|
||||||
|
/* compiler allocates external registers R27 down */
|
||||||
|
#define REGEXT 27
|
||||||
|
#define REGSB 28
|
||||||
|
#define REGFP 29
|
||||||
|
#define REGLINK 30
|
||||||
|
#define REGSP 31
|
||||||
|
#define REGZERO 31
|
||||||
|
|
||||||
|
#define NFREG 32
|
||||||
|
#define FREGRET 0
|
||||||
|
#define FREGMIN 7
|
||||||
|
#define FREGEXT 15
|
||||||
|
|
||||||
|
/* compiler allocates register variables F0 up */
|
||||||
|
/* compiler allocates external registers F15 down */
|
||||||
|
|
||||||
|
enum as
|
||||||
|
{
|
||||||
|
AXXX,
|
||||||
|
|
||||||
|
AADC,
|
||||||
|
AADCS,
|
||||||
|
AADCSW,
|
||||||
|
AADCW,
|
||||||
|
AADD,
|
||||||
|
AADDS,
|
||||||
|
AADDSW,
|
||||||
|
AADDW,
|
||||||
|
AADR,
|
||||||
|
AADRP,
|
||||||
|
AAND,
|
||||||
|
AANDS,
|
||||||
|
AANDSW,
|
||||||
|
AANDW,
|
||||||
|
AASR,
|
||||||
|
AASRW,
|
||||||
|
AAT,
|
||||||
|
AB,
|
||||||
|
ABFI,
|
||||||
|
ABFIW,
|
||||||
|
ABFM,
|
||||||
|
ABFMW,
|
||||||
|
ABFXIL,
|
||||||
|
ABFXILW,
|
||||||
|
ABIC,
|
||||||
|
ABICS,
|
||||||
|
ABICSW,
|
||||||
|
ABICW,
|
||||||
|
ABL,
|
||||||
|
ABRK,
|
||||||
|
ACBNZ,
|
||||||
|
ACBNZW,
|
||||||
|
ACBZ,
|
||||||
|
ACBZW,
|
||||||
|
ACCMN,
|
||||||
|
ACCMNW,
|
||||||
|
ACCMP,
|
||||||
|
ACCMPW,
|
||||||
|
ACINC,
|
||||||
|
ACINCW,
|
||||||
|
ACINV,
|
||||||
|
ACINVW,
|
||||||
|
ACLREX,
|
||||||
|
ACLS,
|
||||||
|
ACLSW,
|
||||||
|
ACLZ,
|
||||||
|
ACLZW,
|
||||||
|
ACMN,
|
||||||
|
ACMNW,
|
||||||
|
ACMP,
|
||||||
|
ACMPW,
|
||||||
|
ACNEG,
|
||||||
|
ACNEGW,
|
||||||
|
ACRC32B,
|
||||||
|
ACRC32CB,
|
||||||
|
ACRC32CH,
|
||||||
|
ACRC32CW,
|
||||||
|
ACRC32CX,
|
||||||
|
ACRC32H,
|
||||||
|
ACRC32W,
|
||||||
|
ACRC32X,
|
||||||
|
ACSEL,
|
||||||
|
ACSELW,
|
||||||
|
ACSET,
|
||||||
|
ACSETM,
|
||||||
|
ACSETMW,
|
||||||
|
ACSETW,
|
||||||
|
ACSINC,
|
||||||
|
ACSINCW,
|
||||||
|
ACSINV,
|
||||||
|
ACSINVW,
|
||||||
|
ACSNEG,
|
||||||
|
ACSNEGW,
|
||||||
|
ADC,
|
||||||
|
ADCPS1,
|
||||||
|
ADCPS2,
|
||||||
|
ADCPS3,
|
||||||
|
ADMB,
|
||||||
|
ADRPS,
|
||||||
|
ADSB,
|
||||||
|
AEON,
|
||||||
|
AEONW,
|
||||||
|
AEOR,
|
||||||
|
AEORW,
|
||||||
|
AERET,
|
||||||
|
AEXTR,
|
||||||
|
AEXTRW,
|
||||||
|
AHINT,
|
||||||
|
AHLT,
|
||||||
|
AHVC,
|
||||||
|
AIC,
|
||||||
|
AISB,
|
||||||
|
ALDAR,
|
||||||
|
ALDARB,
|
||||||
|
ALDARH,
|
||||||
|
ALDARW,
|
||||||
|
ALDAXP,
|
||||||
|
ALDAXPW,
|
||||||
|
ALDAXR,
|
||||||
|
ALDAXRB,
|
||||||
|
ALDAXRH,
|
||||||
|
ALDAXRW,
|
||||||
|
ALDXR,
|
||||||
|
ALDXRB,
|
||||||
|
ALDXRH,
|
||||||
|
ALDXRW,
|
||||||
|
ALDXP,
|
||||||
|
ALDXPW,
|
||||||
|
ALSL,
|
||||||
|
ALSLW,
|
||||||
|
ALSR,
|
||||||
|
ALSRW,
|
||||||
|
AMADD,
|
||||||
|
AMADDW,
|
||||||
|
AMNEG,
|
||||||
|
AMNEGW,
|
||||||
|
AMOVK,
|
||||||
|
AMOVKW,
|
||||||
|
AMOVN,
|
||||||
|
AMOVNW,
|
||||||
|
AMOVZ,
|
||||||
|
AMOVZW,
|
||||||
|
AMRS,
|
||||||
|
AMSR,
|
||||||
|
AMSUB,
|
||||||
|
AMSUBW,
|
||||||
|
AMUL,
|
||||||
|
AMULW,
|
||||||
|
AMVN,
|
||||||
|
AMVNW,
|
||||||
|
ANEG,
|
||||||
|
ANEGS,
|
||||||
|
ANEGSW,
|
||||||
|
ANEGW,
|
||||||
|
ANGC,
|
||||||
|
ANGCS,
|
||||||
|
ANGCSW,
|
||||||
|
ANGCW,
|
||||||
|
ANOP,
|
||||||
|
AORN,
|
||||||
|
AORNW,
|
||||||
|
AORR,
|
||||||
|
AORRW,
|
||||||
|
APRFM,
|
||||||
|
APRFUM,
|
||||||
|
ARBIT,
|
||||||
|
ARBITW,
|
||||||
|
AREM,
|
||||||
|
AREMW,
|
||||||
|
ARET,
|
||||||
|
AREV,
|
||||||
|
AREV16,
|
||||||
|
AREV16W,
|
||||||
|
AREV32,
|
||||||
|
AREVW,
|
||||||
|
AROR,
|
||||||
|
ARORW,
|
||||||
|
ASBC,
|
||||||
|
ASBCS,
|
||||||
|
ASBCSW,
|
||||||
|
ASBCW,
|
||||||
|
ASBFIZ,
|
||||||
|
ASBFIZW,
|
||||||
|
ASBFM,
|
||||||
|
ASBFMW,
|
||||||
|
ASBFX,
|
||||||
|
ASBFXW,
|
||||||
|
ASDIV,
|
||||||
|
ASDIVW,
|
||||||
|
ASEV,
|
||||||
|
ASEVL,
|
||||||
|
ASMADDL,
|
||||||
|
ASMC,
|
||||||
|
ASMNEGL,
|
||||||
|
ASMSUBL,
|
||||||
|
ASMULH,
|
||||||
|
ASMULL,
|
||||||
|
ASTXR,
|
||||||
|
ASTXRB,
|
||||||
|
ASTXRH,
|
||||||
|
ASTXP,
|
||||||
|
ASTXPW,
|
||||||
|
ASTXRW,
|
||||||
|
ASTLP,
|
||||||
|
ASTLPW,
|
||||||
|
ASTLR,
|
||||||
|
ASTLRB,
|
||||||
|
ASTLRH,
|
||||||
|
ASTLRW,
|
||||||
|
ASTLXP,
|
||||||
|
ASTLXPW,
|
||||||
|
ASTLXR,
|
||||||
|
ASTLXRB,
|
||||||
|
ASTLXRH,
|
||||||
|
ASTLXRW,
|
||||||
|
ASUB,
|
||||||
|
ASUBS,
|
||||||
|
ASUBSW,
|
||||||
|
ASUBW,
|
||||||
|
ASVC,
|
||||||
|
ASXTB,
|
||||||
|
ASXTBW,
|
||||||
|
ASXTH,
|
||||||
|
ASXTHW,
|
||||||
|
ASXTW,
|
||||||
|
ASYS,
|
||||||
|
ASYSL,
|
||||||
|
ATBNZ,
|
||||||
|
ATBZ,
|
||||||
|
ATLBI,
|
||||||
|
ATST,
|
||||||
|
ATSTW,
|
||||||
|
AUBFIZ,
|
||||||
|
AUBFIZW,
|
||||||
|
AUBFM,
|
||||||
|
AUBFMW,
|
||||||
|
AUBFX,
|
||||||
|
AUBFXW,
|
||||||
|
AUDIV,
|
||||||
|
AUDIVW,
|
||||||
|
AUMADDL,
|
||||||
|
AUMNEGL,
|
||||||
|
AUMSUBL,
|
||||||
|
AUMULH,
|
||||||
|
AUMULL,
|
||||||
|
AUREM,
|
||||||
|
AUREMW,
|
||||||
|
AUXTB,
|
||||||
|
AUXTH,
|
||||||
|
AUXTW,
|
||||||
|
AUXTBW,
|
||||||
|
AUXTHW,
|
||||||
|
AWFE,
|
||||||
|
AWFI,
|
||||||
|
AYIELD,
|
||||||
|
|
||||||
|
AMOVB,
|
||||||
|
AMOVBU,
|
||||||
|
AMOVH,
|
||||||
|
AMOVHU,
|
||||||
|
AMOVW,
|
||||||
|
AMOVWU,
|
||||||
|
AMOV,
|
||||||
|
AMOVNP,
|
||||||
|
AMOVNPW,
|
||||||
|
AMOVP,
|
||||||
|
AMOVPD,
|
||||||
|
AMOVPQ,
|
||||||
|
AMOVPS,
|
||||||
|
AMOVPSW,
|
||||||
|
AMOVPW,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not reorder or fragment the conditional branch
|
||||||
|
* opcodes, or the predication code will break
|
||||||
|
*/
|
||||||
|
ABEQ,
|
||||||
|
ABNE,
|
||||||
|
ABCS,
|
||||||
|
ABHS,
|
||||||
|
ABCC,
|
||||||
|
ABLO,
|
||||||
|
ABMI,
|
||||||
|
ABPL,
|
||||||
|
ABVS,
|
||||||
|
ABVC,
|
||||||
|
ABHI,
|
||||||
|
ABLS,
|
||||||
|
ABGE,
|
||||||
|
ABLT,
|
||||||
|
ABGT,
|
||||||
|
ABLE,
|
||||||
|
|
||||||
|
AFABSD,
|
||||||
|
AFABSS,
|
||||||
|
AFADDD,
|
||||||
|
AFADDS,
|
||||||
|
AFCCMPD,
|
||||||
|
AFCCMPED,
|
||||||
|
AFCCMPS,
|
||||||
|
AFCCMPES,
|
||||||
|
AFCMPD,
|
||||||
|
AFCMPED,
|
||||||
|
AFCMPES,
|
||||||
|
AFCMPS,
|
||||||
|
AFCVTSD,
|
||||||
|
AFCVTDS,
|
||||||
|
AFCVTZSD,
|
||||||
|
AFCVTZSDW,
|
||||||
|
AFCVTZSS,
|
||||||
|
AFCVTZSSW,
|
||||||
|
AFCVTZUD,
|
||||||
|
AFCVTZUDW,
|
||||||
|
AFCVTZUS,
|
||||||
|
AFCVTZUSW,
|
||||||
|
AFDIVD,
|
||||||
|
AFDIVS,
|
||||||
|
AFMOVD,
|
||||||
|
AFMOVS,
|
||||||
|
AFMULD,
|
||||||
|
AFMULS,
|
||||||
|
AFNEGD,
|
||||||
|
AFNEGS,
|
||||||
|
AFSQRTD,
|
||||||
|
AFSQRTS,
|
||||||
|
AFSUBD,
|
||||||
|
AFSUBS,
|
||||||
|
ASCVTFD,
|
||||||
|
ASCVTFS,
|
||||||
|
ASCVTFWD,
|
||||||
|
ASCVTFWS,
|
||||||
|
AUCVTFD,
|
||||||
|
AUCVTFS,
|
||||||
|
AUCVTFWD,
|
||||||
|
AUCVTFWS,
|
||||||
|
|
||||||
|
ATEXT,
|
||||||
|
ADATA,
|
||||||
|
AGLOBL,
|
||||||
|
AHISTORY,
|
||||||
|
ANAME,
|
||||||
|
AWORD,
|
||||||
|
ADYNT,
|
||||||
|
AINIT,
|
||||||
|
ABCASE,
|
||||||
|
ACASE,
|
||||||
|
ADWORD,
|
||||||
|
ASIGNAME,
|
||||||
|
AGOK,
|
||||||
|
ARETURN,
|
||||||
|
AEND,
|
||||||
|
|
||||||
|
AFCSELS,
|
||||||
|
AFCSELD,
|
||||||
|
AFMAXS,
|
||||||
|
AFMINS,
|
||||||
|
AFMAXD,
|
||||||
|
AFMIND,
|
||||||
|
AFMAXNMS,
|
||||||
|
AFMAXNMD,
|
||||||
|
AFNMULS,
|
||||||
|
AFNMULD,
|
||||||
|
AFRINTNS,
|
||||||
|
AFRINTND,
|
||||||
|
AFRINTPS,
|
||||||
|
AFRINTPD,
|
||||||
|
AFRINTMS,
|
||||||
|
AFRINTMD,
|
||||||
|
AFRINTZS,
|
||||||
|
AFRINTZD,
|
||||||
|
AFRINTAS,
|
||||||
|
AFRINTAD,
|
||||||
|
AFRINTXS,
|
||||||
|
AFRINTXD,
|
||||||
|
AFRINTIS,
|
||||||
|
AFRINTID,
|
||||||
|
AFMADDS,
|
||||||
|
AFMADDD,
|
||||||
|
AFMSUBS,
|
||||||
|
AFMSUBD,
|
||||||
|
AFNMADDS,
|
||||||
|
AFNMADDD,
|
||||||
|
AFNMSUBS,
|
||||||
|
AFNMSUBD,
|
||||||
|
AFMINNMS,
|
||||||
|
AFMINNMD,
|
||||||
|
AFCVTDH,
|
||||||
|
AFCVTHS,
|
||||||
|
AFCVTHD,
|
||||||
|
AFCVTSH,
|
||||||
|
|
||||||
|
AAESD,
|
||||||
|
AAESE,
|
||||||
|
AAESIMC,
|
||||||
|
AAESMC,
|
||||||
|
ASHA1C,
|
||||||
|
ASHA1H,
|
||||||
|
ASHA1M,
|
||||||
|
ASHA1P,
|
||||||
|
ASHA1SU0,
|
||||||
|
ASHA1SU1,
|
||||||
|
ASHA256H,
|
||||||
|
ASHA256H2,
|
||||||
|
ASHA256SU0,
|
||||||
|
ASHA256SU1,
|
||||||
|
|
||||||
|
ALAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* form offset parameter to SYS; special register number */
|
||||||
|
#define SYSARG5(op0,op1,Cn,Cm,op2) ((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5)
|
||||||
|
#define SYSARG4(op1,Cn,Cm,op2) SYSARG5(0,op1,Cn,Cm,op2)
|
||||||
|
|
||||||
|
/* type/name */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
D_GOK = 0,
|
||||||
|
D_NONE,
|
||||||
|
|
||||||
|
/* name */
|
||||||
|
D_EXTERN,
|
||||||
|
D_STATIC,
|
||||||
|
D_AUTO,
|
||||||
|
D_PARAM,
|
||||||
|
|
||||||
|
/* type */
|
||||||
|
D_BRANCH,
|
||||||
|
D_OREG, /* offset(reg) */
|
||||||
|
D_XPRE, /* offset(reg)! - pre-indexed */
|
||||||
|
D_XPOST, /* (reg)offset! - post-indexed */
|
||||||
|
D_CONST, /* 32-bit constant */
|
||||||
|
D_DCONST, /* 64-bit constant */
|
||||||
|
D_FCONST, /* floating-point constant */
|
||||||
|
D_SCONST, /* short string constant */
|
||||||
|
D_REG, /* Rn = Wn or Xn depending on op */
|
||||||
|
D_SP, /* distinguish REGSP from REGZERO */
|
||||||
|
D_FREG, /* Fn = Sn or Dn depending on op */
|
||||||
|
D_VREG, /* Vn = SIMD register */
|
||||||
|
D_SPR, /* special processor register */
|
||||||
|
D_FILE,
|
||||||
|
D_OCONST, /* absolute address constant (unused) */
|
||||||
|
D_FILE1,
|
||||||
|
|
||||||
|
D_SHIFT, /* Rm{, ashift #imm} */
|
||||||
|
D_PAIR, /* pair of gprs */
|
||||||
|
D_ADDR, /* address constant (dynamic loading) */
|
||||||
|
D_ADRP, /* pc-relative addressing, page */
|
||||||
|
D_ADRLO, /* low-order 12 bits of external reference */
|
||||||
|
D_EXTREG, /* Rm{, ext #imm} */
|
||||||
|
D_ROFF, /* register offset Rn+ext(Rm)<<s */
|
||||||
|
D_COND, /* condition EQ, NE, etc */
|
||||||
|
D_VLANE, /* Vn lane */
|
||||||
|
D_VSET, /* set of Vn */
|
||||||
|
|
||||||
|
/* offset iff type is D_SPR */
|
||||||
|
D_DAIF = SYSARG5(3,3,4,2,1),
|
||||||
|
D_NZCV = SYSARG5(3,3,4,2,0),
|
||||||
|
D_FPSR = SYSARG5(3,3,4,4,1),
|
||||||
|
D_FPCR = SYSARG5(3,3,4,4,0),
|
||||||
|
D_SPSR_EL1 = SYSARG5(3,0,4,0,0),
|
||||||
|
D_ELR_EL1 = SYSARG5(3,0,4,0,1),
|
||||||
|
D_SPSR_EL2 = SYSARG5(3,4,4,0,0),
|
||||||
|
D_ELR_EL2 = SYSARG5(3,4,4,0,1),
|
||||||
|
// D_SPSR_EL3 = SYSARG5(3,x,4,x,x),
|
||||||
|
// D_ELR_EL3 = SYSARG5(3,x,4,x,x),
|
||||||
|
// D_LR_EL0 = SYSARG5(3,x,4,x,x),
|
||||||
|
D_CurrentEL = SYSARG5(3,0,4,2,2),
|
||||||
|
D_SP_EL0 = SYSARG5(3,0,4,1,0),
|
||||||
|
// D_SP_EL1 = SYSARG5(3,x,4,x,x),
|
||||||
|
// D_SP_EL2 = SYSARG5(3,x,4,x,x),
|
||||||
|
D_SPSel = SYSARG5(3,0,4,2,0),
|
||||||
|
// D_SPSR_abt = SYSARG5(3,x,4,x,x),
|
||||||
|
// D_SPSR_fiq = SYSARG5(3,x,4,x,x),
|
||||||
|
// D_SPSR_ieq = SYSARG5(3,x,4,x,x),
|
||||||
|
// D_SPSR_und = SYSARG5(3,x,4,x,x),
|
||||||
|
D_DAIFSet = (1<<30)|0,
|
||||||
|
D_DAIFClr = (1<<30)|1
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this is the ranlib header
|
||||||
|
*/
|
||||||
|
#define SYMDEF "__.SYMDEF"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this is the simulated IEEE floating point
|
||||||
|
*/
|
||||||
|
typedef struct Ieee Ieee;
|
||||||
|
struct Ieee
|
||||||
|
{
|
||||||
|
long l; /* contains ls-man 0xffffffff */
|
||||||
|
long h; /* contains sign 0x80000000
|
||||||
|
exp 0x7ff00000
|
||||||
|
ms-man 0x000fffff */
|
||||||
|
};
|
1256
sys/src/cmd/7c/cgen.c
Normal file
1256
sys/src/cmd/7c/cgen.c
Normal file
File diff suppressed because it is too large
Load diff
358
sys/src/cmd/7c/gc.h
Normal file
358
sys/src/cmd/7c/gc.h
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
#include "../cc/cc.h"
|
||||||
|
#include "../7c/7.out.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 7c/arm64
|
||||||
|
* Arm64
|
||||||
|
*/
|
||||||
|
#define SZ_CHAR 1
|
||||||
|
#define SZ_SHORT 2
|
||||||
|
#define SZ_INT 4
|
||||||
|
#define SZ_LONG 4
|
||||||
|
#define SZ_IND 8
|
||||||
|
#define SZ_FLOAT 4
|
||||||
|
#define SZ_VLONG 8
|
||||||
|
#define SZ_DOUBLE 8
|
||||||
|
#define FNX 100
|
||||||
|
#define BTRUE 0x1000
|
||||||
|
|
||||||
|
typedef struct Adr Adr;
|
||||||
|
typedef struct Prog Prog;
|
||||||
|
typedef struct Case Case;
|
||||||
|
typedef struct C1 C1;
|
||||||
|
typedef struct Multab Multab;
|
||||||
|
typedef struct Hintab Hintab;
|
||||||
|
typedef struct Var Var;
|
||||||
|
typedef struct Reg Reg;
|
||||||
|
typedef struct Rgn Rgn;
|
||||||
|
|
||||||
|
|
||||||
|
struct Adr
|
||||||
|
{
|
||||||
|
vlong offset;
|
||||||
|
double dval;
|
||||||
|
char sval[NSNAME];
|
||||||
|
Ieee ieee;
|
||||||
|
|
||||||
|
Sym* sym;
|
||||||
|
char type;
|
||||||
|
char reg;
|
||||||
|
char name;
|
||||||
|
char etype;
|
||||||
|
};
|
||||||
|
#define A ((Adr*)0)
|
||||||
|
|
||||||
|
#define INDEXED 9
|
||||||
|
struct Prog
|
||||||
|
{
|
||||||
|
Adr from;
|
||||||
|
Adr to;
|
||||||
|
Prog* link;
|
||||||
|
long lineno;
|
||||||
|
ushort as;
|
||||||
|
char reg;
|
||||||
|
uchar scond;
|
||||||
|
};
|
||||||
|
#define P ((Prog*)0)
|
||||||
|
|
||||||
|
struct Case
|
||||||
|
{
|
||||||
|
Case* link;
|
||||||
|
vlong val;
|
||||||
|
long label;
|
||||||
|
char def;
|
||||||
|
char isv;
|
||||||
|
};
|
||||||
|
#define C ((Case*)0)
|
||||||
|
|
||||||
|
struct C1
|
||||||
|
{
|
||||||
|
vlong val;
|
||||||
|
long label;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Multab
|
||||||
|
{
|
||||||
|
long val;
|
||||||
|
char code[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Hintab
|
||||||
|
{
|
||||||
|
ushort val;
|
||||||
|
char hint[10];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Var
|
||||||
|
{
|
||||||
|
vlong offset;
|
||||||
|
Sym* sym;
|
||||||
|
char name;
|
||||||
|
char etype;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Reg
|
||||||
|
{
|
||||||
|
long pc;
|
||||||
|
long rpo; /* reverse post ordering */
|
||||||
|
|
||||||
|
Bits set;
|
||||||
|
Bits use1;
|
||||||
|
Bits use2;
|
||||||
|
|
||||||
|
Bits refbehind;
|
||||||
|
Bits refahead;
|
||||||
|
Bits calbehind;
|
||||||
|
Bits calahead;
|
||||||
|
Bits regdiff;
|
||||||
|
Bits act;
|
||||||
|
|
||||||
|
long regu;
|
||||||
|
long loop; /* could be shorter */
|
||||||
|
|
||||||
|
|
||||||
|
Reg* log5;
|
||||||
|
long active;
|
||||||
|
|
||||||
|
Reg* p1;
|
||||||
|
Reg* p2;
|
||||||
|
Reg* p2link;
|
||||||
|
Reg* s1;
|
||||||
|
Reg* s2;
|
||||||
|
Reg* link;
|
||||||
|
Prog* prog;
|
||||||
|
};
|
||||||
|
#define R ((Reg*)0)
|
||||||
|
|
||||||
|
#define NRGN 1000 /* was 600; raised for paranoia.c */
|
||||||
|
struct Rgn
|
||||||
|
{
|
||||||
|
Reg* enter;
|
||||||
|
short cost;
|
||||||
|
short varno;
|
||||||
|
short regno;
|
||||||
|
};
|
||||||
|
|
||||||
|
EXTERN long breakpc;
|
||||||
|
EXTERN long nbreak;
|
||||||
|
EXTERN Case* cases;
|
||||||
|
EXTERN Node constnode;
|
||||||
|
EXTERN Node fconstnode;
|
||||||
|
EXTERN Node vconstnode;
|
||||||
|
EXTERN long continpc;
|
||||||
|
EXTERN long curarg;
|
||||||
|
EXTERN long cursafe;
|
||||||
|
EXTERN Prog* firstp;
|
||||||
|
EXTERN Prog* lastp;
|
||||||
|
EXTERN long maxargsafe;
|
||||||
|
EXTERN int mnstring;
|
||||||
|
EXTERN Multab multab[20];
|
||||||
|
EXTERN int hintabsize;
|
||||||
|
EXTERN Node* nodrat;
|
||||||
|
EXTERN Node* nodret;
|
||||||
|
EXTERN Node* nodsafe;
|
||||||
|
EXTERN long nrathole;
|
||||||
|
EXTERN long nstring;
|
||||||
|
EXTERN Prog* p;
|
||||||
|
EXTERN long pc;
|
||||||
|
EXTERN Node regnode;
|
||||||
|
EXTERN Node qregnode;
|
||||||
|
EXTERN char string[NSNAME];
|
||||||
|
EXTERN Sym* symrathole;
|
||||||
|
EXTERN Node znode;
|
||||||
|
EXTERN Prog zprog;
|
||||||
|
EXTERN char reg[NREG+NFREG];
|
||||||
|
EXTERN long exregoffset;
|
||||||
|
EXTERN long exfregoffset;
|
||||||
|
EXTERN int suppress;
|
||||||
|
EXTERN uchar typechlpv[NTYPE];
|
||||||
|
|
||||||
|
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
|
||||||
|
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
|
||||||
|
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
|
||||||
|
#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
|
||||||
|
|
||||||
|
#define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32))
|
||||||
|
|
||||||
|
#define CLOAD 4
|
||||||
|
#define CREF 5
|
||||||
|
#define CINF 1000
|
||||||
|
#define LOOP 3
|
||||||
|
|
||||||
|
EXTERN Rgn region[NRGN];
|
||||||
|
EXTERN Rgn* rgp;
|
||||||
|
EXTERN int nregion;
|
||||||
|
EXTERN int nvar;
|
||||||
|
|
||||||
|
EXTERN Bits externs;
|
||||||
|
EXTERN Bits params;
|
||||||
|
EXTERN Bits consts;
|
||||||
|
EXTERN Bits addrs;
|
||||||
|
|
||||||
|
EXTERN long regbits;
|
||||||
|
EXTERN long exregbits;
|
||||||
|
|
||||||
|
EXTERN int change;
|
||||||
|
|
||||||
|
EXTERN Reg* firstr;
|
||||||
|
EXTERN Reg* lastr;
|
||||||
|
EXTERN Reg zreg;
|
||||||
|
EXTERN Reg* freer;
|
||||||
|
EXTERN Var var[NVAR];
|
||||||
|
EXTERN long* idom;
|
||||||
|
EXTERN Reg** rpo2r;
|
||||||
|
EXTERN long maxnr;
|
||||||
|
|
||||||
|
extern char* anames[];
|
||||||
|
extern Hintab hintab[];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sgen.c
|
||||||
|
*/
|
||||||
|
void codgen(Node*, Node*);
|
||||||
|
void gen(Node*);
|
||||||
|
void noretval(int);
|
||||||
|
void usedset(Node*, int);
|
||||||
|
void xcom(Node*);
|
||||||
|
int bcomplex(Node*, Node*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cgen.c
|
||||||
|
*/
|
||||||
|
int castup(Type*, Type*);
|
||||||
|
void cgen(Node*, Node*);
|
||||||
|
void cgenrel(Node*, Node*, int);
|
||||||
|
int cond(int);
|
||||||
|
int hardconst(Node*);
|
||||||
|
void reglcgen(Node*, Node*, Node*);
|
||||||
|
void layout(Node*, Node*, int, int, Node*);
|
||||||
|
void lcgen(Node*, Node*);
|
||||||
|
void bcgen(Node*, int);
|
||||||
|
void boolgen(Node*, int, Node*);
|
||||||
|
void sugen(Node*, Node*, long);
|
||||||
|
void layout(Node*, Node*, int, int, Node*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* txt.c
|
||||||
|
*/
|
||||||
|
void ginit(void);
|
||||||
|
void gclean(void);
|
||||||
|
void nextpc(void);
|
||||||
|
void gargs(Node*, Node*, Node*);
|
||||||
|
void garg1(Node*, Node*, Node*, int, Node**);
|
||||||
|
Node* nodconst(long);
|
||||||
|
Node* nod32const(vlong);
|
||||||
|
Node* nodfconst(double);
|
||||||
|
void nodreg(Node*, Node*, int);
|
||||||
|
void regret(Node*, Node*);
|
||||||
|
void regalloc(Node*, Node*, Node*);
|
||||||
|
void regfree(Node*);
|
||||||
|
void regialloc(Node*, Node*, Node*);
|
||||||
|
void regsalloc(Node*, Node*);
|
||||||
|
void regaalloc1(Node*, Node*);
|
||||||
|
void regaalloc(Node*, Node*);
|
||||||
|
void regind(Node*, Node*);
|
||||||
|
void gprep(Node*, Node*);
|
||||||
|
void raddr(Node*, Prog*);
|
||||||
|
void naddr(Node*, Adr*);
|
||||||
|
void gmovm(Node*, Node*, int);
|
||||||
|
void gmove(Node*, Node*);
|
||||||
|
void gmover(Node*, Node*);
|
||||||
|
void gins(int a, Node*, Node*);
|
||||||
|
void gopcode(int, Node*, Node*, Node*);
|
||||||
|
int samaddr(Node*, Node*);
|
||||||
|
void gbranch(int);
|
||||||
|
void patch(Prog*, long);
|
||||||
|
int sconst(Node*);
|
||||||
|
int sval(long);
|
||||||
|
void gpseudo(int, Sym*, Node*);
|
||||||
|
int usableoffset(Node*, vlong, Node*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* swt.c
|
||||||
|
*/
|
||||||
|
int swcmp(void*, void*);
|
||||||
|
void doswit(Node*);
|
||||||
|
void swit1(C1*, int, long, Node*);
|
||||||
|
void swit2(C1*, int, long, Node*, Node*);
|
||||||
|
void casf(void);
|
||||||
|
void bitload(Node*, Node*, Node*, Node*, Node*);
|
||||||
|
void bitstore(Node*, Node*, Node*, Node*, Node*);
|
||||||
|
long outstring(char*, long);
|
||||||
|
int mulcon(Node*, Node*);
|
||||||
|
Multab* mulcon0(long);
|
||||||
|
void nullwarn(Node*, Node*);
|
||||||
|
void gextern(Sym*, Node*, long, long);
|
||||||
|
void outcode(void);
|
||||||
|
void ieeedtod(Ieee*, double);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list
|
||||||
|
*/
|
||||||
|
void listinit(void);
|
||||||
|
int Pconv(Fmt*);
|
||||||
|
int Aconv(Fmt*);
|
||||||
|
int Dconv(Fmt*);
|
||||||
|
int Sconv(Fmt*);
|
||||||
|
int Nconv(Fmt*);
|
||||||
|
int Bconv(Fmt*);
|
||||||
|
int Rconv(Fmt*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reg.c
|
||||||
|
*/
|
||||||
|
Reg* rega(void);
|
||||||
|
int rcmp(void*, void*);
|
||||||
|
void regopt(Prog*);
|
||||||
|
void addmove(Reg*, int, int, int);
|
||||||
|
Bits mkvar(Adr*, int);
|
||||||
|
void prop(Reg*, Bits, Bits);
|
||||||
|
void loopit(Reg*, long);
|
||||||
|
void synch(Reg*, Bits);
|
||||||
|
ulong allreg(ulong, Rgn*);
|
||||||
|
void paint1(Reg*, int);
|
||||||
|
ulong paint2(Reg*, int);
|
||||||
|
void paint3(Reg*, int, long, int);
|
||||||
|
void addreg(Adr*, int);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* peep.c
|
||||||
|
*/
|
||||||
|
void peep(void);
|
||||||
|
void excise(Reg*);
|
||||||
|
Reg* uniqp(Reg*);
|
||||||
|
Reg* uniqs(Reg*);
|
||||||
|
int regtyp(Adr*);
|
||||||
|
int regzer(Adr*);
|
||||||
|
int anyvar(Adr*);
|
||||||
|
int subprop(Reg*);
|
||||||
|
int copyprop(Reg*);
|
||||||
|
int shiftprop(Reg*);
|
||||||
|
void constprop(Adr*, Adr*, Reg*);
|
||||||
|
int copy1(Adr*, Adr*, Reg*, int);
|
||||||
|
int copyu(Prog*, Adr*, Adr*);
|
||||||
|
|
||||||
|
int copyas(Adr*, Adr*);
|
||||||
|
int copyau(Adr*, Adr*);
|
||||||
|
int copyau1(Prog*, Adr*);
|
||||||
|
int copysub(Adr*, Adr*, Adr*, int);
|
||||||
|
int copysub1(Prog*, Adr*, Adr*, int);
|
||||||
|
|
||||||
|
long RtoB(int);
|
||||||
|
long FtoB(int);
|
||||||
|
int BtoR(long);
|
||||||
|
int BtoF(long);
|
||||||
|
|
||||||
|
void predicate(void);
|
||||||
|
int isbranch(Prog *);
|
||||||
|
int predicable(Prog *p);
|
||||||
|
int modifiescpsr(Prog *p);
|
||||||
|
|
||||||
|
#pragma varargck type "A" int
|
||||||
|
#pragma varargck type "A" uint
|
||||||
|
#pragma varargck type "B" Bits
|
||||||
|
#pragma varargck type "D" Adr*
|
||||||
|
#pragma varargck type "N" Adr*
|
||||||
|
#pragma varargck type "R" Adr*
|
||||||
|
#pragma varargck type "P" Prog*
|
||||||
|
#pragma varargck type "S" char*
|
329
sys/src/cmd/7c/list.c
Normal file
329
sys/src/cmd/7c/list.c
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
#define EXTERN
|
||||||
|
#include "gc.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
listinit(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
fmtinstall('A', Aconv);
|
||||||
|
fmtinstall('P', Pconv);
|
||||||
|
fmtinstall('S', Sconv);
|
||||||
|
fmtinstall('N', Nconv);
|
||||||
|
fmtinstall('B', Bconv);
|
||||||
|
fmtinstall('D', Dconv);
|
||||||
|
fmtinstall('R', Rconv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Bconv(Fmt *fp)
|
||||||
|
{
|
||||||
|
char str[STRINGSZ], ss[STRINGSZ], *s;
|
||||||
|
Bits bits;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
str[0] = 0;
|
||||||
|
bits = va_arg(fp->args, Bits);
|
||||||
|
while(bany(&bits)) {
|
||||||
|
i = bnum(bits);
|
||||||
|
if(str[0])
|
||||||
|
strcat(str, " ");
|
||||||
|
if(var[i].sym == S) {
|
||||||
|
snprint(ss, sizeof(ss), "$%lld", var[i].offset);
|
||||||
|
s = ss;
|
||||||
|
} else
|
||||||
|
s = var[i].sym->name;
|
||||||
|
if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
|
||||||
|
break;
|
||||||
|
strcat(str, s);
|
||||||
|
bits.b[i/32] &= ~(1L << (i%32));
|
||||||
|
}
|
||||||
|
return fmtstrcpy(fp, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *conds[] = {
|
||||||
|
".EQ", ".NE", ".CS", ".CC",
|
||||||
|
".MI", ".PL", ".VS", ".VC",
|
||||||
|
".HI", ".LS", ".GE", ".LT",
|
||||||
|
".GT", ".LE", "", ".NV",
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
Pconv(Fmt *fp)
|
||||||
|
{
|
||||||
|
char str[STRINGSZ];
|
||||||
|
Prog *p;
|
||||||
|
int a;
|
||||||
|
|
||||||
|
p = va_arg(fp->args, Prog*);
|
||||||
|
a = p->as;
|
||||||
|
if(a == ADATA)
|
||||||
|
snprint(str, sizeof(str), " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
|
||||||
|
else
|
||||||
|
if(p->as == ATEXT)
|
||||||
|
snprint(str, sizeof(str), " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
|
||||||
|
else
|
||||||
|
if(p->reg == NREG)
|
||||||
|
snprint(str, sizeof(str), " %A %D,%D", a, &p->from, &p->to);
|
||||||
|
else
|
||||||
|
if(p->from.type != D_FREG)
|
||||||
|
snprint(str, sizeof(str), " %A %D,R%d,%D", a, &p->from, p->reg, &p->to);
|
||||||
|
else
|
||||||
|
snprint(str, sizeof(str), " %A %D,F%d,%D", a, &p->from, p->reg, &p->to);
|
||||||
|
return fmtstrcpy(fp, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Aconv(Fmt *fp)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
int a;
|
||||||
|
|
||||||
|
a = va_arg(fp->args, int);
|
||||||
|
s = "???";
|
||||||
|
if(a >= AXXX && a < ALAST)
|
||||||
|
s = anames[a];
|
||||||
|
return fmtstrcpy(fp, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Dconv(Fmt *fp)
|
||||||
|
{
|
||||||
|
char str[STRINGSZ];
|
||||||
|
Adr *a;
|
||||||
|
char *op;
|
||||||
|
int v;
|
||||||
|
static char *extop[] = {".UB", ".UH", ".UW", ".UX", ".SB", ".SH", ".SW", ".SX"};
|
||||||
|
|
||||||
|
a = va_arg(fp->args, Adr*);
|
||||||
|
switch(a->type) {
|
||||||
|
|
||||||
|
default:
|
||||||
|
snprint(str, sizeof(str), "GOK-type(%d)", a->type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_NONE:
|
||||||
|
str[0] = 0;
|
||||||
|
if(a->name != D_NONE || a->reg != NREG || a->sym != S)
|
||||||
|
snprint(str, sizeof(str), "%N(R%d)(NONE)", a, a->reg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_CONST:
|
||||||
|
if(a->reg != NREG)
|
||||||
|
snprint(str, sizeof(str), "$%N(R%d)", a, a->reg);
|
||||||
|
else
|
||||||
|
snprint(str, sizeof(str), "$%N", a);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_SHIFT:
|
||||||
|
v = a->offset;
|
||||||
|
op = "<<>>->@>" + (((v>>5) & 3) << 1);
|
||||||
|
if(v & (1<<4))
|
||||||
|
snprint(str, sizeof(str), "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
|
||||||
|
else
|
||||||
|
snprint(str, sizeof(str), "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
|
||||||
|
if(a->reg != NREG)
|
||||||
|
sprint(str+strlen(str), "(R%d)", a->reg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_OREG:
|
||||||
|
if(a->reg != NREG)
|
||||||
|
snprint(str, sizeof(str), "%N(R%d)", a, a->reg);
|
||||||
|
else
|
||||||
|
snprint(str, sizeof(str), "%N", a);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_XPRE:
|
||||||
|
if(a->reg != NREG)
|
||||||
|
snprint(str, sizeof(str), "%N(R%d)!", a, a->reg);
|
||||||
|
else
|
||||||
|
snprint(str, sizeof(str), "%N!", a);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_XPOST:
|
||||||
|
if(a->reg != NREG)
|
||||||
|
snprint(str, sizeof(str), "(R%d)%N!", a->reg, a);
|
||||||
|
else
|
||||||
|
snprint(str, sizeof(str), "%N!", a);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_EXTREG:
|
||||||
|
v = a->offset;
|
||||||
|
if(v & (7<<10))
|
||||||
|
snprint(str, sizeof(str), "R%d%s<<%d", (v>>16)&31, extop[(v>>13)&7], (v>>10)&7);
|
||||||
|
else
|
||||||
|
snprint(str, sizeof(str), "R%d%s", (v>>16)&31, extop[(v>>13)&7]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_REG:
|
||||||
|
snprint(str, sizeof(str), "R%d", a->reg);
|
||||||
|
if(a->name != D_NONE || a->sym != S)
|
||||||
|
snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_SP:
|
||||||
|
if(a->name != D_NONE || a->sym != S)
|
||||||
|
snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
|
||||||
|
else
|
||||||
|
strcpy(str, "SP");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_FREG:
|
||||||
|
snprint(str, sizeof(str), "F%d", a->reg);
|
||||||
|
if(a->name != D_NONE || a->sym != S)
|
||||||
|
snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case D_SPR:
|
||||||
|
switch((ulong)a->offset){
|
||||||
|
case D_FPSR:
|
||||||
|
sprint(str, "FPSR");
|
||||||
|
break;
|
||||||
|
case D_FPCR:
|
||||||
|
sprint(str, "FPCR");
|
||||||
|
break;
|
||||||
|
case D_NZCV:
|
||||||
|
sprint(str, "NZCV");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sprint(str, "SPR(%#llux)", a->offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(a->name != D_NONE || a->sym != S)
|
||||||
|
snprint(str, sizeof(str), "%N(SPR(%lld))(REG)", a, a->offset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_BRANCH:
|
||||||
|
snprint(str, sizeof(str), "%lld(PC)", a->offset-pc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_FCONST:
|
||||||
|
snprint(str, sizeof(str), "$%.17e", a->dval);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_SCONST:
|
||||||
|
snprint(str, sizeof(str), "$\"%S\"", a->sval);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return fmtstrcpy(fp, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Rconv(Fmt *fp)
|
||||||
|
{
|
||||||
|
char str[STRINGSZ], *p, *e;
|
||||||
|
Adr *a;
|
||||||
|
int i, v;
|
||||||
|
|
||||||
|
a = va_arg(fp->args, Adr*);
|
||||||
|
snprint(str, sizeof(str), "GOK-reglist");
|
||||||
|
switch(a->type) {
|
||||||
|
case D_CONST:
|
||||||
|
if(a->reg != NREG)
|
||||||
|
break;
|
||||||
|
if(a->sym != S)
|
||||||
|
break;
|
||||||
|
v = a->offset;
|
||||||
|
p = str;
|
||||||
|
e = str+sizeof(str);
|
||||||
|
for(i=0; i<NREG; i++) {
|
||||||
|
if(v & (1<<i)) {
|
||||||
|
if(p == str)
|
||||||
|
p = seprint(p, e, "[R%d", i);
|
||||||
|
else
|
||||||
|
p = seprint(p, e, ",R%d", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seprint(p, e, "]");
|
||||||
|
}
|
||||||
|
return fmtstrcpy(fp, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Sconv(Fmt *fp)
|
||||||
|
{
|
||||||
|
int i, c;
|
||||||
|
char str[STRINGSZ], *p, *a;
|
||||||
|
|
||||||
|
a = va_arg(fp->args, char*);
|
||||||
|
p = str;
|
||||||
|
for(i=0; i<NSNAME; i++) {
|
||||||
|
c = a[i] & 0xff;
|
||||||
|
if(c >= 'a' && c <= 'z' ||
|
||||||
|
c >= 'A' && c <= 'Z' ||
|
||||||
|
c >= '0' && c <= '9' ||
|
||||||
|
c == ' ' || c == '%') {
|
||||||
|
*p++ = c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*p++ = '\\';
|
||||||
|
switch(c) {
|
||||||
|
case 0:
|
||||||
|
*p++ = 'z';
|
||||||
|
continue;
|
||||||
|
case '\\':
|
||||||
|
case '"':
|
||||||
|
*p++ = c;
|
||||||
|
continue;
|
||||||
|
case '\n':
|
||||||
|
*p++ = 'n';
|
||||||
|
continue;
|
||||||
|
case '\t':
|
||||||
|
*p++ = 't';
|
||||||
|
continue;
|
||||||
|
case '\r':
|
||||||
|
*p++ = 'r';
|
||||||
|
continue;
|
||||||
|
case '\f':
|
||||||
|
*p++ = 'f';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*p++ = (c>>6) + '0';
|
||||||
|
*p++ = ((c>>3) & 7) + '0';
|
||||||
|
*p++ = (c & 7) + '0';
|
||||||
|
}
|
||||||
|
*p = 0;
|
||||||
|
return fmtstrcpy(fp, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Nconv(Fmt *fp)
|
||||||
|
{
|
||||||
|
char str[STRINGSZ];
|
||||||
|
Adr *a;
|
||||||
|
Sym *s;
|
||||||
|
|
||||||
|
a = va_arg(fp->args, Adr*);
|
||||||
|
s = a->sym;
|
||||||
|
if(s == S) {
|
||||||
|
snprint(str, sizeof(str), "%lld", a->offset);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
switch(a->name) {
|
||||||
|
default:
|
||||||
|
snprint(str, sizeof(str), "GOK-name(%d)", a->name);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_NONE:
|
||||||
|
snprint(str, sizeof(str), "%lld", a->offset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_EXTERN:
|
||||||
|
snprint(str, sizeof(str), "%s+%lld(SB)", s->name, a->offset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_STATIC:
|
||||||
|
snprint(str, sizeof(str), "%s<>+%lld(SB)", s->name, a->offset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_AUTO:
|
||||||
|
snprint(str, sizeof(str), "%s-%lld(SP)", s->name, -a->offset);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_PARAM:
|
||||||
|
snprint(str, sizeof(str), "%s+%lld(FP)", s->name, a->offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return fmtstrcpy(fp, str);
|
||||||
|
}
|
81
sys/src/cmd/7c/machcap.c
Normal file
81
sys/src/cmd/7c/machcap.c
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#include "gc.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
machcap(Node *n)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(n == Z)
|
||||||
|
return 1; /* test */
|
||||||
|
|
||||||
|
switch(n->op) {
|
||||||
|
case OMUL:
|
||||||
|
case OLMUL:
|
||||||
|
case OASMUL:
|
||||||
|
case OASLMUL:
|
||||||
|
if(typechlv[n->type->etype])
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OADD:
|
||||||
|
case OAND:
|
||||||
|
case OOR:
|
||||||
|
case OSUB:
|
||||||
|
case OXOR:
|
||||||
|
case OASHL:
|
||||||
|
case OLSHR:
|
||||||
|
case OASHR:
|
||||||
|
if(typechlv[n->left->type->etype])
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OCAST:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case OCOND:
|
||||||
|
case OCOMMA:
|
||||||
|
case OLIST:
|
||||||
|
case OANDAND:
|
||||||
|
case OOROR:
|
||||||
|
case ONOT:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case OASADD:
|
||||||
|
case OASSUB:
|
||||||
|
case OASAND:
|
||||||
|
case OASOR:
|
||||||
|
case OASXOR:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case OASASHL:
|
||||||
|
case OASASHR:
|
||||||
|
case OASLSHR:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case OPOSTINC:
|
||||||
|
case OPOSTDEC:
|
||||||
|
case OPREINC:
|
||||||
|
case OPREDEC:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case OEQ:
|
||||||
|
case ONE:
|
||||||
|
case OLE:
|
||||||
|
case OGT:
|
||||||
|
case OLT:
|
||||||
|
case OGE:
|
||||||
|
case OHI:
|
||||||
|
case OHS:
|
||||||
|
case OLO:
|
||||||
|
case OLS:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case ONEG:
|
||||||
|
if(typechlv[n->left->type->etype])
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OCOM:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
15
sys/src/cmd/7c/mkenam
Normal file
15
sys/src/cmd/7c/mkenam
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
ed - ../7c/7.out.h <<'!'
|
||||||
|
v/^ A/d
|
||||||
|
,s/^ A/ "/
|
||||||
|
g/ .*$/s///
|
||||||
|
,s/,*$/",/
|
||||||
|
1i
|
||||||
|
char* anames[] =
|
||||||
|
{
|
||||||
|
.
|
||||||
|
$a
|
||||||
|
};
|
||||||
|
.
|
||||||
|
w enam.c
|
||||||
|
Q
|
||||||
|
!
|
41
sys/src/cmd/7c/mkfile
Normal file
41
sys/src/cmd/7c/mkfile
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
</$objtype/mkfile
|
||||||
|
|
||||||
|
TARG=7c
|
||||||
|
OFILES=\
|
||||||
|
cgen.$O\
|
||||||
|
enam.$O\
|
||||||
|
list.$O\
|
||||||
|
machcap.$O\
|
||||||
|
mul.$O\
|
||||||
|
peep.$O\
|
||||||
|
pgen.$O\
|
||||||
|
pswt.$O\
|
||||||
|
reg.$O\
|
||||||
|
sgen.$O\
|
||||||
|
swt.$O\
|
||||||
|
txt.$O\
|
||||||
|
|
||||||
|
HFILES=\
|
||||||
|
gc.h\
|
||||||
|
7.out.h\
|
||||||
|
../cc/cc.h\
|
||||||
|
|
||||||
|
LIB=../cc/cc.a$O
|
||||||
|
|
||||||
|
BIN=/$objtype/bin
|
||||||
|
</sys/src/cmd/mkone
|
||||||
|
|
||||||
|
$LIB: ../cc/cc.h
|
||||||
|
cd ../cc
|
||||||
|
mk install
|
||||||
|
|
||||||
|
%.$O: ../cc/%.c
|
||||||
|
$CC $CFLAGS ../cc/$stem.c
|
||||||
|
|
||||||
|
t:V: $O.out
|
||||||
|
$O.out -S t
|
||||||
|
$LD -o t.out t.$O
|
||||||
|
t.out
|
||||||
|
|
||||||
|
enam.c: 7.out.h
|
||||||
|
rc mkenam
|
609
sys/src/cmd/7c/mul.c
Normal file
609
sys/src/cmd/7c/mul.c
Normal file
|
@ -0,0 +1,609 @@
|
||||||
|
#include "gc.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* code sequences for multiply by constant.
|
||||||
|
* [a-l][0-3]
|
||||||
|
* lsl $(A-'a'),r0,r1
|
||||||
|
* [+][0-7]
|
||||||
|
* add r0,r1,r2
|
||||||
|
* [-][0-7]
|
||||||
|
* sub r0,r1,r2
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int maxmulops = 3; /* max # of ops to replace mul with */
|
||||||
|
static int multabp;
|
||||||
|
static long mulval;
|
||||||
|
static char* mulcp;
|
||||||
|
static long valmax;
|
||||||
|
static int shmax;
|
||||||
|
|
||||||
|
static int docode(char *hp, char *cp, int r0, int r1);
|
||||||
|
static int gen1(int len);
|
||||||
|
static int gen2(int len, long r1);
|
||||||
|
static int gen3(int len, long r0, long r1, int flag);
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SR1 = 1<<0, /* r1 has been shifted */
|
||||||
|
SR0 = 1<<1, /* r0 has been shifted */
|
||||||
|
UR1 = 1<<2, /* r1 has not been used */
|
||||||
|
UR0 = 1<<3, /* r0 has not been used */
|
||||||
|
};
|
||||||
|
|
||||||
|
Multab*
|
||||||
|
mulcon0(long v)
|
||||||
|
{
|
||||||
|
int a1, a2, g;
|
||||||
|
Multab *m, *m1;
|
||||||
|
char hint[10];
|
||||||
|
|
||||||
|
if(v < 0)
|
||||||
|
v = -v;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* look in cache
|
||||||
|
*/
|
||||||
|
m = multab;
|
||||||
|
for(g=0; g<nelem(multab); g++) {
|
||||||
|
if(m->val == v) {
|
||||||
|
if(m->code[0] == 0)
|
||||||
|
return 0;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* select a spot in cache to overwrite
|
||||||
|
*/
|
||||||
|
multabp++;
|
||||||
|
if(multabp < 0 || multabp >= nelem(multab))
|
||||||
|
multabp = 0;
|
||||||
|
m = multab+multabp;
|
||||||
|
m->val = v;
|
||||||
|
mulval = v;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* look in execption hint table
|
||||||
|
*/
|
||||||
|
a1 = 0;
|
||||||
|
a2 = hintabsize;
|
||||||
|
for(;;) {
|
||||||
|
if(a1 >= a2)
|
||||||
|
goto no;
|
||||||
|
g = (a2 + a1)/2;
|
||||||
|
if(v < hintab[g].val) {
|
||||||
|
a2 = g;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(v > hintab[g].val) {
|
||||||
|
a1 = g+1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(docode(hintab[g].hint, m->code, 1, 0))
|
||||||
|
return m;
|
||||||
|
print("multiply table failure %ld\n", v);
|
||||||
|
m->code[0] = 0;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
no:
|
||||||
|
/*
|
||||||
|
* try to search
|
||||||
|
*/
|
||||||
|
hint[0] = 0;
|
||||||
|
for(g=1; g<=maxmulops; g++) {
|
||||||
|
if(g >= maxmulops && v >= 65535)
|
||||||
|
break;
|
||||||
|
mulcp = hint+g;
|
||||||
|
*mulcp = 0;
|
||||||
|
if(gen1(g)) {
|
||||||
|
if(docode(hint, m->code, 1, 0))
|
||||||
|
return m;
|
||||||
|
print("multiply table failure %ld\n", v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* try a recur followed by a shift
|
||||||
|
*/
|
||||||
|
g = 0;
|
||||||
|
while(!(v & 1)) {
|
||||||
|
g++;
|
||||||
|
v >>= 1;
|
||||||
|
}
|
||||||
|
if(g) {
|
||||||
|
m1 = mulcon0(v);
|
||||||
|
if(m1) {
|
||||||
|
strcpy(m->code, m1->code);
|
||||||
|
sprint(strchr(m->code, 0), "%c0", g+'a');
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->code[0] = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
docode(char *hp, char *cp, int r0, int r1)
|
||||||
|
{
|
||||||
|
int c, i;
|
||||||
|
|
||||||
|
c = *hp++;
|
||||||
|
*cp = c;
|
||||||
|
cp += 2;
|
||||||
|
switch(c) {
|
||||||
|
default:
|
||||||
|
c -= 'a';
|
||||||
|
if(c < 1 || c >= 30)
|
||||||
|
break;
|
||||||
|
for(i=0; i<4; i++) {
|
||||||
|
switch(i) {
|
||||||
|
case 0:
|
||||||
|
if(docode(hp, cp, r0<<c, r1))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if(docode(hp, cp, r1<<c, r1))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(docode(hp, cp, r0, r0<<c))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(docode(hp, cp, r0, r1<<c))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '+':
|
||||||
|
for(i=0; i<8; i++) {
|
||||||
|
cp[-1] = i+'0';
|
||||||
|
switch(i) {
|
||||||
|
case 1:
|
||||||
|
if(docode(hp, cp, r0+r1, r1))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if(docode(hp, cp, r0, r0+r1))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
for(i=0; i<8; i++) {
|
||||||
|
cp[-1] = i+'0';
|
||||||
|
switch(i) {
|
||||||
|
case 1:
|
||||||
|
if(docode(hp, cp, r0-r1, r1))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(docode(hp, cp, r1-r0, r1))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if(docode(hp, cp, r0, r0-r1))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if(docode(hp, cp, r0, r1-r0))
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
if(r0 == mulval)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
cp[-1] = i+'0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen1(int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(shmax=1; shmax<30; shmax++) {
|
||||||
|
valmax = 1<<shmax;
|
||||||
|
if(valmax >= mulval)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(mulval == 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
len--;
|
||||||
|
for(i=1; i<=shmax; i++)
|
||||||
|
if(gen2(len, 1<<i)) {
|
||||||
|
*--mulcp = 'a'+i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen2(int len, long r1)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(len <= 0) {
|
||||||
|
if(r1 == mulval)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
len--;
|
||||||
|
if(len == 0)
|
||||||
|
goto calcr0;
|
||||||
|
|
||||||
|
if(gen3(len, r1, r1+1, UR1)) {
|
||||||
|
i = '+';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if(gen3(len, r1-1, r1, UR0)) {
|
||||||
|
i = '-';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if(gen3(len, 1, r1+1, UR1)) {
|
||||||
|
i = '+';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if(gen3(len, 1, r1-1, UR1)) {
|
||||||
|
i = '-';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
calcr0:
|
||||||
|
if(mulval == r1+1) {
|
||||||
|
i = '+';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if(mulval == r1-1) {
|
||||||
|
i = '-';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
*--mulcp = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen3(int len, long r0, long r1, int flag)
|
||||||
|
{
|
||||||
|
int i, f1, f2;
|
||||||
|
long x;
|
||||||
|
|
||||||
|
if(r0 <= 0 ||
|
||||||
|
r0 >= r1 ||
|
||||||
|
r1 > valmax)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
len--;
|
||||||
|
if(len == 0)
|
||||||
|
goto calcr0;
|
||||||
|
|
||||||
|
if(!(flag & UR1)) {
|
||||||
|
f1 = UR1|SR1;
|
||||||
|
for(i=1; i<=shmax; i++) {
|
||||||
|
x = r0<<i;
|
||||||
|
if(x > valmax)
|
||||||
|
break;
|
||||||
|
if(gen3(len, r0, x, f1)) {
|
||||||
|
i += 'a';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(flag & UR0)) {
|
||||||
|
f1 = UR1|SR1;
|
||||||
|
for(i=1; i<=shmax; i++) {
|
||||||
|
x = r1<<i;
|
||||||
|
if(x > valmax)
|
||||||
|
break;
|
||||||
|
if(gen3(len, r1, x, f1)) {
|
||||||
|
i += 'a';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(flag & SR1)) {
|
||||||
|
f1 = UR1|SR1|(flag&UR0);
|
||||||
|
for(i=1; i<=shmax; i++) {
|
||||||
|
x = r1<<i;
|
||||||
|
if(x > valmax)
|
||||||
|
break;
|
||||||
|
if(gen3(len, r0, x, f1)) {
|
||||||
|
i += 'a';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(flag & SR0)) {
|
||||||
|
f1 = UR0|SR0|(flag&(SR1|UR1));
|
||||||
|
|
||||||
|
f2 = UR1|SR1;
|
||||||
|
if(flag & UR1)
|
||||||
|
f2 |= UR0;
|
||||||
|
if(flag & SR1)
|
||||||
|
f2 |= SR0;
|
||||||
|
|
||||||
|
for(i=1; i<=shmax; i++) {
|
||||||
|
x = r0<<i;
|
||||||
|
if(x > valmax)
|
||||||
|
break;
|
||||||
|
if(x > r1) {
|
||||||
|
if(gen3(len, r1, x, f2)) {
|
||||||
|
i += 'a';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if(gen3(len, x, r1, f1)) {
|
||||||
|
i += 'a';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x = r1+r0;
|
||||||
|
if(gen3(len, r0, x, UR1)) {
|
||||||
|
i = '+';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gen3(len, r1, x, UR1)) {
|
||||||
|
i = '+';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = r1-r0;
|
||||||
|
if(gen3(len, x, r1, UR0)) {
|
||||||
|
i = '-';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x > r0) {
|
||||||
|
if(gen3(len, r0, x, UR1)) {
|
||||||
|
i = '-';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if(gen3(len, x, r0, UR0)) {
|
||||||
|
i = '-';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
calcr0:
|
||||||
|
f1 = flag & (UR0|UR1);
|
||||||
|
if(f1 == UR1) {
|
||||||
|
for(i=1; i<=shmax; i++) {
|
||||||
|
x = r1<<i;
|
||||||
|
if(x >= mulval) {
|
||||||
|
if(x == mulval) {
|
||||||
|
i += 'a';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mulval == r1+r0) {
|
||||||
|
i = '+';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if(mulval == r1-r0) {
|
||||||
|
i = '-';
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
*--mulcp = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hint table has numbers that
|
||||||
|
* the search algorithm fails on.
|
||||||
|
* <1000:
|
||||||
|
* all numbers
|
||||||
|
* <5000:
|
||||||
|
* ÷ by 5
|
||||||
|
* <10000:
|
||||||
|
* ÷ by 50
|
||||||
|
* <65536:
|
||||||
|
* ÷ by 250
|
||||||
|
*/
|
||||||
|
Hintab hintab[] =
|
||||||
|
{
|
||||||
|
683, "b++d+e+",
|
||||||
|
687, "b+e++e-",
|
||||||
|
691, "b++d+e+",
|
||||||
|
731, "b++d+e+",
|
||||||
|
811, "b++d+i+",
|
||||||
|
821, "b++e+e+",
|
||||||
|
843, "b+d++e+",
|
||||||
|
851, "b+f-+e-",
|
||||||
|
853, "b++e+e+",
|
||||||
|
877, "c++++g-",
|
||||||
|
933, "b+c++g-",
|
||||||
|
981, "c-+e-d+",
|
||||||
|
1375, "b+c+b+h-",
|
||||||
|
1675, "d+b++h+",
|
||||||
|
2425, "c++f-e+",
|
||||||
|
2675, "c+d++f-",
|
||||||
|
2750, "b+d-b+h-",
|
||||||
|
2775, "c-+g-e-",
|
||||||
|
3125, "b++e+g+",
|
||||||
|
3275, "b+c+g+e+",
|
||||||
|
3350, "c++++i+",
|
||||||
|
3475, "c-+e-f-",
|
||||||
|
3525, "c-+d+g-",
|
||||||
|
3625, "c-+e-j+",
|
||||||
|
3675, "b+d+d+e+",
|
||||||
|
3725, "b+d-+h+",
|
||||||
|
3925, "b+d+f-d-",
|
||||||
|
4275, "b+g++e+",
|
||||||
|
4325, "b+h-+d+",
|
||||||
|
4425, "b+b+g-j-",
|
||||||
|
4525, "b+d-d+f+",
|
||||||
|
4675, "c++d-g+",
|
||||||
|
4775, "b+d+b+g-",
|
||||||
|
4825, "c+c-+i-",
|
||||||
|
4850, "c++++i-",
|
||||||
|
4925, "b++e-g-",
|
||||||
|
4975, "c+f++e-",
|
||||||
|
5500, "b+g-c+d+",
|
||||||
|
6700, "d+b++i+",
|
||||||
|
9700, "d++++j-",
|
||||||
|
11000, "b+f-c-h-",
|
||||||
|
11750, "b+d+g+j-",
|
||||||
|
12500, "b+c+e-k+",
|
||||||
|
13250, "b+d+e-f+",
|
||||||
|
13750, "b+h-c-d+",
|
||||||
|
14250, "b+g-c+e-",
|
||||||
|
14500, "c+f+j-d-",
|
||||||
|
14750, "d-g--f+",
|
||||||
|
16750, "b+e-d-n+",
|
||||||
|
17750, "c+h-b+e+",
|
||||||
|
18250, "d+b+h-d+",
|
||||||
|
18750, "b+g-++f+",
|
||||||
|
19250, "b+e+b+h+",
|
||||||
|
19750, "b++h--f-",
|
||||||
|
20250, "b+e-l-c+",
|
||||||
|
20750, "c++bi+e-",
|
||||||
|
21250, "b+i+l+c+",
|
||||||
|
22000, "b+e+d-g-",
|
||||||
|
22250, "b+d-h+k-",
|
||||||
|
22750, "b+d-e-g+",
|
||||||
|
23250, "b+c+h+e-",
|
||||||
|
23500, "b+g-c-g-",
|
||||||
|
23750, "b+g-b+h-",
|
||||||
|
24250, "c++g+m-",
|
||||||
|
24750, "b+e+e+j-",
|
||||||
|
25000, "b++dh+g+",
|
||||||
|
25250, "b+e+d-g-",
|
||||||
|
25750, "b+e+b+j+",
|
||||||
|
26250, "b+h+c+e+",
|
||||||
|
26500, "b+h+c+g+",
|
||||||
|
26750, "b+d+e+g-",
|
||||||
|
27250, "b+e+e+f+",
|
||||||
|
27500, "c-i-c-d+",
|
||||||
|
27750, "b+bd++j+",
|
||||||
|
28250, "d-d-++i-",
|
||||||
|
28500, "c+c-h-e-",
|
||||||
|
29000, "b+g-d-f+",
|
||||||
|
29500, "c+h+++e-",
|
||||||
|
29750, "b+g+f-c+",
|
||||||
|
30250, "b+f-g-c+",
|
||||||
|
33500, "c-f-d-n+",
|
||||||
|
33750, "b+d-b+j-",
|
||||||
|
34250, "c+e+++i+",
|
||||||
|
35250, "e+b+d+k+",
|
||||||
|
35500, "c+e+d-g-",
|
||||||
|
35750, "c+i-++e+",
|
||||||
|
36250, "b+bh-d+e+",
|
||||||
|
36500, "c+c-h-e-",
|
||||||
|
36750, "d+e--i+",
|
||||||
|
37250, "b+g+g+b+",
|
||||||
|
37500, "b+h-b+f+",
|
||||||
|
37750, "c+be++j-",
|
||||||
|
38500, "b+e+b+i+",
|
||||||
|
38750, "d+i-b+d+",
|
||||||
|
39250, "b+g-l-+d+",
|
||||||
|
39500, "b+g-c+g-",
|
||||||
|
39750, "b+bh-c+f-",
|
||||||
|
40250, "b+bf+d+g-",
|
||||||
|
40500, "b+g-c+g+",
|
||||||
|
40750, "c+b+i-e+",
|
||||||
|
41250, "d++bf+h+",
|
||||||
|
41500, "b+j+c+d-",
|
||||||
|
41750, "c+f+b+h-",
|
||||||
|
42500, "c+h++g+",
|
||||||
|
42750, "b+g+d-f-",
|
||||||
|
43250, "b+l-e+d-",
|
||||||
|
43750, "c+bd+h+f-",
|
||||||
|
44000, "b+f+g-d-",
|
||||||
|
44250, "b+d-g--f+",
|
||||||
|
44500, "c+e+c+h+",
|
||||||
|
44750, "b+e+d-h-",
|
||||||
|
45250, "b++g+j-g+",
|
||||||
|
45500, "c+d+e-g+",
|
||||||
|
45750, "b+d-h-e-",
|
||||||
|
46250, "c+bd++j+",
|
||||||
|
46500, "b+d-c-j-",
|
||||||
|
46750, "e-e-b+g-",
|
||||||
|
47000, "b+c+d-j-",
|
||||||
|
47250, "b+e+e-g-",
|
||||||
|
47500, "b+g-c-h-",
|
||||||
|
47750, "b+f-c+h-",
|
||||||
|
48250, "d--h+n-",
|
||||||
|
48500, "b+c-g+m-",
|
||||||
|
48750, "b+e+e-g+",
|
||||||
|
49500, "c-f+e+j-",
|
||||||
|
49750, "c+c+g++f-",
|
||||||
|
50000, "b+e+e+k+",
|
||||||
|
50250, "b++i++g+",
|
||||||
|
50500, "c+g+f-i+",
|
||||||
|
50750, "b+e+d+k-",
|
||||||
|
51500, "b+i+c-f+",
|
||||||
|
51750, "b+bd+g-e-",
|
||||||
|
52250, "b+d+g-j+",
|
||||||
|
52500, "c+c+f+g+",
|
||||||
|
52750, "b+c+e+i+",
|
||||||
|
53000, "b+i+c+g+",
|
||||||
|
53500, "c+g+g-n+",
|
||||||
|
53750, "b+j+d-c+",
|
||||||
|
54250, "b+d-g-j-",
|
||||||
|
54500, "c-f+e+f+",
|
||||||
|
54750, "b+f-+c+g+",
|
||||||
|
55000, "b+g-d-g-",
|
||||||
|
55250, "b+e+e+g+",
|
||||||
|
55500, "b+cd++j+",
|
||||||
|
55750, "b+bh-d-f-",
|
||||||
|
56250, "c+d-b+j-",
|
||||||
|
56500, "c+d+c+i+",
|
||||||
|
56750, "b+e+d++h-",
|
||||||
|
57000, "b+d+g-f+",
|
||||||
|
57250, "b+f-m+d-",
|
||||||
|
57750, "b+i+c+e-",
|
||||||
|
58000, "b+e+d+h+",
|
||||||
|
58250, "c+b+g+g+",
|
||||||
|
58750, "d-e-j--e+",
|
||||||
|
59000, "d-i-+e+",
|
||||||
|
59250, "e--h-m+",
|
||||||
|
59500, "c+c-h+f-",
|
||||||
|
59750, "b+bh-e+i-",
|
||||||
|
60250, "b+bh-e-e-",
|
||||||
|
60500, "c+c-g-g-",
|
||||||
|
60750, "b+e-l-e-",
|
||||||
|
61250, "b+g-g-c+",
|
||||||
|
61750, "b+g-c+g+",
|
||||||
|
62250, "f--+c-i-",
|
||||||
|
62750, "e+f--+g+",
|
||||||
|
64750, "b+f+d+p-",
|
||||||
|
};
|
||||||
|
int hintabsize = nelem(hintab);
|
1546
sys/src/cmd/7c/peep.c
Normal file
1546
sys/src/cmd/7c/peep.c
Normal file
File diff suppressed because it is too large
Load diff
1160
sys/src/cmd/7c/reg.c
Normal file
1160
sys/src/cmd/7c/reg.c
Normal file
File diff suppressed because it is too large
Load diff
247
sys/src/cmd/7c/sgen.c
Normal file
247
sys/src/cmd/7c/sgen.c
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
#include "gc.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
noretval(int n)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(n & 1) {
|
||||||
|
gins(ANOP, Z, Z);
|
||||||
|
p->to.type = D_REG;
|
||||||
|
p->to.reg = REGRET;
|
||||||
|
}
|
||||||
|
if(n & 2) {
|
||||||
|
gins(ANOP, Z, Z);
|
||||||
|
p->to.type = D_FREG;
|
||||||
|
p->to.reg = FREGRET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate addressability as follows
|
||||||
|
* CONST ==> 20 $value
|
||||||
|
* NAME ==> 10 name
|
||||||
|
* REGISTER ==> 11 register
|
||||||
|
* INDREG ==> 12 *[(reg)+offset]
|
||||||
|
* &10 ==> 2 $name
|
||||||
|
* ADD(2, 20) ==> 2 $name+offset
|
||||||
|
* ADD(3, 20) ==> 3 $(reg)+offset
|
||||||
|
* &12 ==> 3 $(reg)+offset
|
||||||
|
* *11 ==> 11 ??
|
||||||
|
* *2 ==> 10 name
|
||||||
|
* *3 ==> 12 *(reg)+offset
|
||||||
|
* calculate complexity (number of registers)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xcom(Node *n)
|
||||||
|
{
|
||||||
|
Node *l, *r;
|
||||||
|
int t;
|
||||||
|
|
||||||
|
if(n == Z)
|
||||||
|
return;
|
||||||
|
l = n->left;
|
||||||
|
r = n->right;
|
||||||
|
n->addable = 0;
|
||||||
|
n->complex = 0;
|
||||||
|
switch(n->op) {
|
||||||
|
case OCONST:
|
||||||
|
n->addable = 20;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case OREGISTER:
|
||||||
|
n->addable = 11;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case OINDREG:
|
||||||
|
n->addable = 12;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ONAME:
|
||||||
|
n->addable = 10;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case OADDR:
|
||||||
|
xcom(l);
|
||||||
|
if(l->addable == 10)
|
||||||
|
n->addable = 2;
|
||||||
|
if(l->addable == 12)
|
||||||
|
n->addable = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OIND:
|
||||||
|
xcom(l);
|
||||||
|
if(l->addable == 11)
|
||||||
|
n->addable = 12;
|
||||||
|
if(l->addable == 3)
|
||||||
|
n->addable = 12;
|
||||||
|
if(l->addable == 2)
|
||||||
|
n->addable = 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OADD:
|
||||||
|
xcom(l);
|
||||||
|
xcom(r);
|
||||||
|
if(l->addable == 20) {
|
||||||
|
if(r->addable == 2)
|
||||||
|
n->addable = 2;
|
||||||
|
if(r->addable == 3)
|
||||||
|
n->addable = 3;
|
||||||
|
}
|
||||||
|
if(r->addable == 20) {
|
||||||
|
if(l->addable == 2)
|
||||||
|
n->addable = 2;
|
||||||
|
if(l->addable == 3)
|
||||||
|
n->addable = 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OASMUL:
|
||||||
|
case OASLMUL:
|
||||||
|
xcom(l);
|
||||||
|
xcom(r);
|
||||||
|
t = vlog(r);
|
||||||
|
if(t >= 0) {
|
||||||
|
n->op = OASASHL;
|
||||||
|
r->vconst = t;
|
||||||
|
r->type = types[TINT];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OMUL:
|
||||||
|
case OLMUL:
|
||||||
|
xcom(l);
|
||||||
|
xcom(r);
|
||||||
|
t = vlog(r);
|
||||||
|
if(t >= 0) {
|
||||||
|
n->op = OASHL;
|
||||||
|
r->vconst = t;
|
||||||
|
r->type = types[TINT];
|
||||||
|
}
|
||||||
|
t = vlog(l);
|
||||||
|
if(t >= 0) {
|
||||||
|
n->op = OASHL;
|
||||||
|
n->left = r;
|
||||||
|
n->right = l;
|
||||||
|
r = l;
|
||||||
|
l = n->left;
|
||||||
|
r->vconst = t;
|
||||||
|
r->type = types[TINT];
|
||||||
|
simplifyshift(n);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OASLDIV:
|
||||||
|
xcom(l);
|
||||||
|
xcom(r);
|
||||||
|
t = vlog(r);
|
||||||
|
if(t >= 0) {
|
||||||
|
n->op = OASLSHR;
|
||||||
|
r->vconst = t;
|
||||||
|
r->type = types[TINT];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OLDIV:
|
||||||
|
xcom(l);
|
||||||
|
xcom(r);
|
||||||
|
t = vlog(r);
|
||||||
|
if(t >= 0) {
|
||||||
|
n->op = OLSHR;
|
||||||
|
r->vconst = t;
|
||||||
|
r->type = types[TINT];
|
||||||
|
simplifyshift(n);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OASLMOD:
|
||||||
|
xcom(l);
|
||||||
|
xcom(r);
|
||||||
|
t = vlog(r);
|
||||||
|
if(t >= 0) {
|
||||||
|
n->op = OASAND;
|
||||||
|
r->vconst--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OLMOD:
|
||||||
|
xcom(l);
|
||||||
|
xcom(r);
|
||||||
|
t = vlog(r);
|
||||||
|
if(t >= 0) {
|
||||||
|
n->op = OAND;
|
||||||
|
r->vconst--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OLSHR:
|
||||||
|
case OASHL:
|
||||||
|
case OASHR:
|
||||||
|
xcom(l);
|
||||||
|
xcom(r);
|
||||||
|
simplifyshift(n);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if(l != Z)
|
||||||
|
xcom(l);
|
||||||
|
if(r != Z)
|
||||||
|
xcom(r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(n->addable >= 10)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(l != Z)
|
||||||
|
n->complex = l->complex;
|
||||||
|
if(r != Z) {
|
||||||
|
if(r->complex == n->complex)
|
||||||
|
n->complex = r->complex+1;
|
||||||
|
else
|
||||||
|
if(r->complex > n->complex)
|
||||||
|
n->complex = r->complex;
|
||||||
|
}
|
||||||
|
if(n->complex == 0)
|
||||||
|
n->complex++;
|
||||||
|
|
||||||
|
// if(com64(n))
|
||||||
|
// return;
|
||||||
|
|
||||||
|
switch(n->op) {
|
||||||
|
case OFUNC:
|
||||||
|
n->complex = FNX;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OEQ:
|
||||||
|
case ONE:
|
||||||
|
case OLE:
|
||||||
|
case OLT:
|
||||||
|
case OGE:
|
||||||
|
case OGT:
|
||||||
|
case OHI:
|
||||||
|
case OHS:
|
||||||
|
case OLO:
|
||||||
|
case OLS:
|
||||||
|
/*
|
||||||
|
* immediate operators, make const on right
|
||||||
|
*/
|
||||||
|
if(l->op == OCONST) {
|
||||||
|
n->left = r;
|
||||||
|
n->right = l;
|
||||||
|
n->op = invrel[relindex(n->op)];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OADD:
|
||||||
|
case OXOR:
|
||||||
|
case OAND:
|
||||||
|
case OOR:
|
||||||
|
/*
|
||||||
|
* immediate operators, make const on right
|
||||||
|
*/
|
||||||
|
if(l->op == OCONST) {
|
||||||
|
n->left = r;
|
||||||
|
n->right = l;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
654
sys/src/cmd/7c/swt.c
Normal file
654
sys/src/cmd/7c/swt.c
Normal file
|
@ -0,0 +1,654 @@
|
||||||
|
#include "gc.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
swit1(C1 *q, int nc, long def, Node *n)
|
||||||
|
{
|
||||||
|
Node tn;
|
||||||
|
|
||||||
|
regalloc(&tn, ®node, Z);
|
||||||
|
swit2(q, nc, def, n, &tn);
|
||||||
|
regfree(&tn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
swit2(C1 *q, int nc, long def, Node *n, Node *tn)
|
||||||
|
{
|
||||||
|
C1 *r;
|
||||||
|
int i;
|
||||||
|
long v;
|
||||||
|
Prog *sp;
|
||||||
|
|
||||||
|
if(nc >= 3) {
|
||||||
|
i = (q+nc-1)->val - (q+0)->val;
|
||||||
|
if(i > 0 && i < nc*2)
|
||||||
|
goto direct;
|
||||||
|
}
|
||||||
|
if(nc < 5) {
|
||||||
|
for(i=0; i<nc; i++) {
|
||||||
|
if(debug['K'])
|
||||||
|
print("case = %.8llux\n", q->val);
|
||||||
|
gopcode(OEQ, nodconst(q->val), n, Z);
|
||||||
|
patch(p, q->label);
|
||||||
|
q++;
|
||||||
|
}
|
||||||
|
gbranch(OGOTO);
|
||||||
|
patch(p, def);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = nc / 2;
|
||||||
|
r = q+i;
|
||||||
|
if(debug['K'])
|
||||||
|
print("case > %.8llux\n", r->val);
|
||||||
|
gopcode(OGT, nodconst(r->val), n, Z);
|
||||||
|
sp = p;
|
||||||
|
gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */
|
||||||
|
patch(p, r->label);
|
||||||
|
swit2(q, i, def, n, tn);
|
||||||
|
|
||||||
|
if(debug['K'])
|
||||||
|
print("case < %.8llux\n", r->val);
|
||||||
|
patch(sp, pc);
|
||||||
|
swit2(r+1, nc-i-1, def, n, tn);
|
||||||
|
return;
|
||||||
|
|
||||||
|
direct:
|
||||||
|
v = q->val;
|
||||||
|
if(v != 0)
|
||||||
|
gopcode(OSUB, nodconst(v), Z, n);
|
||||||
|
gopcode(OHI, nodconst((q+nc-1)->val - v), n, Z);
|
||||||
|
patch(p, def);
|
||||||
|
gopcode(OCASE, n, Z, tn);
|
||||||
|
for(i=0; i<nc; i++) {
|
||||||
|
if(debug['K'])
|
||||||
|
print("case = %.8llux\n", q->val);
|
||||||
|
while(q->val != v) {
|
||||||
|
nextpc();
|
||||||
|
p->as = ABCASE;
|
||||||
|
patch(p, def);
|
||||||
|
v++;
|
||||||
|
}
|
||||||
|
nextpc();
|
||||||
|
p->as = ABCASE;
|
||||||
|
patch(p, q->label);
|
||||||
|
q++;
|
||||||
|
v++;
|
||||||
|
}
|
||||||
|
gbranch(OGOTO); /* so that regopt() won't be confused */
|
||||||
|
patch(p, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
|
||||||
|
{
|
||||||
|
int sh;
|
||||||
|
long v;
|
||||||
|
Node *l;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* n1 gets adjusted/masked value
|
||||||
|
* n2 gets address of cell
|
||||||
|
* n3 gets contents of cell
|
||||||
|
*/
|
||||||
|
l = b->left;
|
||||||
|
if(n2 != Z) {
|
||||||
|
regalloc(n1, l, nn);
|
||||||
|
reglcgen(n2, l, Z);
|
||||||
|
regalloc(n3, l, Z);
|
||||||
|
gopcode(OAS, n2, Z, n3);
|
||||||
|
gopcode(OAS, n3, Z, n1);
|
||||||
|
} else {
|
||||||
|
regalloc(n1, l, nn);
|
||||||
|
cgen(l, n1);
|
||||||
|
}
|
||||||
|
if(b->type->shift == 0 && typeu[b->type->etype]) {
|
||||||
|
v = ~0 + (1L << b->type->nbits);
|
||||||
|
gopcode(OAND, nodconst(v), Z, n1);
|
||||||
|
} else {
|
||||||
|
sh = 32 - b->type->shift - b->type->nbits;
|
||||||
|
if(sh > 0)
|
||||||
|
gopcode(OASHL, nodconst(sh), Z, n1);
|
||||||
|
sh += b->type->shift;
|
||||||
|
if(sh > 0)
|
||||||
|
if(typeu[b->type->etype])
|
||||||
|
gopcode(OLSHR, nodconst(sh), Z, n1);
|
||||||
|
else
|
||||||
|
gopcode(OASHR, nodconst(sh), Z, n1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
|
||||||
|
{
|
||||||
|
long v;
|
||||||
|
Node nod, *l;
|
||||||
|
int sh;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* n1 has adjusted/masked value
|
||||||
|
* n2 has address of cell
|
||||||
|
* n3 has contents of cell
|
||||||
|
*/
|
||||||
|
l = b->left;
|
||||||
|
regalloc(&nod, l, Z);
|
||||||
|
v = ~0 + (1L << b->type->nbits);
|
||||||
|
gopcode(OAND, nodconst(v), Z, n1);
|
||||||
|
gopcode(OAS, n1, Z, &nod);
|
||||||
|
if(nn != Z)
|
||||||
|
gopcode(OAS, n1, Z, nn);
|
||||||
|
sh = b->type->shift;
|
||||||
|
if(sh > 0)
|
||||||
|
gopcode(OASHL, nodconst(sh), Z, &nod);
|
||||||
|
v <<= sh;
|
||||||
|
gopcode(OAND, nodconst(~v), Z, n3);
|
||||||
|
gopcode(OOR, n3, Z, &nod);
|
||||||
|
gopcode(OAS, &nod, Z, n2);
|
||||||
|
|
||||||
|
regfree(&nod);
|
||||||
|
regfree(n1);
|
||||||
|
regfree(n2);
|
||||||
|
regfree(n3);
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
outstring(char *s, long n)
|
||||||
|
{
|
||||||
|
long r;
|
||||||
|
|
||||||
|
if(suppress)
|
||||||
|
return nstring;
|
||||||
|
r = nstring;
|
||||||
|
while(n) {
|
||||||
|
string[mnstring] = *s++;
|
||||||
|
mnstring++;
|
||||||
|
nstring++;
|
||||||
|
if(mnstring >= NSNAME) {
|
||||||
|
gpseudo(ADATA, symstring, nodconst(0L));
|
||||||
|
p->from.offset += nstring - NSNAME;
|
||||||
|
p->reg = NSNAME;
|
||||||
|
p->to.type = D_SCONST;
|
||||||
|
memmove(p->to.sval, string, NSNAME);
|
||||||
|
mnstring = 0;
|
||||||
|
}
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mulcon(Node *n, Node *nn)
|
||||||
|
{
|
||||||
|
Node *l, *r, nod1, nod2;
|
||||||
|
Multab *m;
|
||||||
|
long v, vs;
|
||||||
|
int o;
|
||||||
|
char code[sizeof(m->code)+2], *p;
|
||||||
|
|
||||||
|
if(typefd[n->type->etype])
|
||||||
|
return 0;
|
||||||
|
l = n->left;
|
||||||
|
r = n->right;
|
||||||
|
if(l->op == OCONST) {
|
||||||
|
l = r;
|
||||||
|
r = n->left;
|
||||||
|
}
|
||||||
|
if(r->op != OCONST)
|
||||||
|
return 0;
|
||||||
|
v = convvtox(r->vconst, n->type->etype);
|
||||||
|
if(v != r->vconst) {
|
||||||
|
if(debug['M'])
|
||||||
|
print("%L multiply conv: %lld\n", n->lineno, r->vconst);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
m = mulcon0(v);
|
||||||
|
if(!m) {
|
||||||
|
if(debug['M'])
|
||||||
|
print("%L multiply table: %lld\n", n->lineno, r->vconst);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(debug['M'] && debug['v'])
|
||||||
|
print("%L multiply: %ld\n", n->lineno, v);
|
||||||
|
|
||||||
|
memmove(code, m->code, sizeof(m->code));
|
||||||
|
code[sizeof(m->code)] = 0;
|
||||||
|
|
||||||
|
p = code;
|
||||||
|
if(p[1] == 'i')
|
||||||
|
p += 2;
|
||||||
|
regalloc(&nod1, n, nn);
|
||||||
|
cgen(l, &nod1);
|
||||||
|
vs = v;
|
||||||
|
regalloc(&nod2, n, Z);
|
||||||
|
|
||||||
|
loop:
|
||||||
|
switch(*p) {
|
||||||
|
case 0:
|
||||||
|
regfree(&nod2);
|
||||||
|
if(vs < 0) {
|
||||||
|
gopcode(OAS, &nod1, Z, &nod1);
|
||||||
|
gopcode(ONEG, &nod1, Z, nn);
|
||||||
|
} else
|
||||||
|
gopcode(OAS, &nod1, Z, nn);
|
||||||
|
regfree(&nod1);
|
||||||
|
return 1;
|
||||||
|
case '+':
|
||||||
|
o = OADD;
|
||||||
|
goto addsub;
|
||||||
|
case '-':
|
||||||
|
o = OSUB;
|
||||||
|
addsub: /* number is r,n,l */
|
||||||
|
v = p[1] - '0';
|
||||||
|
r = &nod1;
|
||||||
|
if(v&4)
|
||||||
|
r = &nod2;
|
||||||
|
n = &nod1;
|
||||||
|
if(v&2)
|
||||||
|
n = &nod2;
|
||||||
|
l = &nod1;
|
||||||
|
if(v&1)
|
||||||
|
l = &nod2;
|
||||||
|
gopcode(o, l, n, r);
|
||||||
|
break;
|
||||||
|
default: /* op is shiftcount, number is r,l */
|
||||||
|
v = p[1] - '0';
|
||||||
|
r = &nod1;
|
||||||
|
if(v&2)
|
||||||
|
r = &nod2;
|
||||||
|
l = &nod1;
|
||||||
|
if(v&1)
|
||||||
|
l = &nod2;
|
||||||
|
v = *p - 'a';
|
||||||
|
if(v < 0 || v >= 32) {
|
||||||
|
diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gopcode(OASHL, nodconst(v), l, r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p += 2;
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gextern(Sym *s, Node *a, long o, long w)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(a->op == OCONST && typev[a->type->etype]) {
|
||||||
|
if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
|
||||||
|
gpseudo(ADATA, s, nod32const(a->vconst>>32));
|
||||||
|
else
|
||||||
|
gpseudo(ADATA, s, nod32const(a->vconst));
|
||||||
|
p->from.offset += o;
|
||||||
|
p->reg = 4;
|
||||||
|
if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
|
||||||
|
gpseudo(ADATA, s, nod32const(a->vconst));
|
||||||
|
else
|
||||||
|
gpseudo(ADATA, s, nod32const(a->vconst>>32));
|
||||||
|
p->from.offset += o + 4;
|
||||||
|
p->reg = 4;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gpseudo(ADATA, s, a);
|
||||||
|
p->from.offset += o;
|
||||||
|
p->reg = w;
|
||||||
|
if(p->to.type == D_OREG)
|
||||||
|
p->to.type = D_CONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zname(Biobuf*, Sym*, int);
|
||||||
|
char* zaddr(char*, Adr*, int);
|
||||||
|
void zwrite(Biobuf*, Prog*, int, int);
|
||||||
|
void outhist(Biobuf*);
|
||||||
|
|
||||||
|
void
|
||||||
|
zwrite(Biobuf *b, Prog *p, int sf, int st)
|
||||||
|
{
|
||||||
|
char bf[100], *bp;
|
||||||
|
long l;
|
||||||
|
|
||||||
|
bf[0] = p->as;
|
||||||
|
bf[1] = p->as>>8;
|
||||||
|
bf[2] = p->reg;
|
||||||
|
l = p->lineno;
|
||||||
|
bf[3] = l;
|
||||||
|
bf[4] = l>>8;
|
||||||
|
bf[5] = l>>16;
|
||||||
|
bf[6] = l>>24;
|
||||||
|
bp = zaddr(bf+7, &p->from, sf);
|
||||||
|
bp = zaddr(bp, &p->to, st);
|
||||||
|
Bwrite(b, bf, bp-bf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
outcode(void)
|
||||||
|
{
|
||||||
|
struct { Sym *sym; short type; } h[NSYM];
|
||||||
|
Prog *p;
|
||||||
|
Sym *s;
|
||||||
|
int sf, st, t, sym;
|
||||||
|
|
||||||
|
if(debug['S']) {
|
||||||
|
for(p = firstp; p != P; p = p->link)
|
||||||
|
if(p->as != ADATA && p->as != AGLOBL)
|
||||||
|
pc--;
|
||||||
|
for(p = firstp; p != P; p = p->link) {
|
||||||
|
print("%P\n", p);
|
||||||
|
if(p->as != ADATA && p->as != AGLOBL)
|
||||||
|
pc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outhist(&outbuf);
|
||||||
|
for(sym=0; sym<NSYM; sym++) {
|
||||||
|
h[sym].sym = S;
|
||||||
|
h[sym].type = 0;
|
||||||
|
}
|
||||||
|
sym = 1;
|
||||||
|
for(p = firstp; p != P; p = p->link) {
|
||||||
|
jackpot:
|
||||||
|
sf = 0;
|
||||||
|
s = p->from.sym;
|
||||||
|
while(s != S) {
|
||||||
|
sf = s->sym;
|
||||||
|
if(sf < 0 || sf >= NSYM)
|
||||||
|
sf = 0;
|
||||||
|
t = p->from.name;
|
||||||
|
if(h[sf].type == t)
|
||||||
|
if(h[sf].sym == s)
|
||||||
|
break;
|
||||||
|
s->sym = sym;
|
||||||
|
zname(&outbuf, s, t);
|
||||||
|
h[sym].sym = s;
|
||||||
|
h[sym].type = t;
|
||||||
|
sf = sym;
|
||||||
|
sym++;
|
||||||
|
if(sym >= NSYM)
|
||||||
|
sym = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
st = 0;
|
||||||
|
s = p->to.sym;
|
||||||
|
while(s != S) {
|
||||||
|
st = s->sym;
|
||||||
|
if(st < 0 || st >= NSYM)
|
||||||
|
st = 0;
|
||||||
|
t = p->to.name;
|
||||||
|
if(h[st].type == t)
|
||||||
|
if(h[st].sym == s)
|
||||||
|
break;
|
||||||
|
s->sym = sym;
|
||||||
|
zname(&outbuf, s, t);
|
||||||
|
h[sym].sym = s;
|
||||||
|
h[sym].type = t;
|
||||||
|
st = sym;
|
||||||
|
sym++;
|
||||||
|
if(sym >= NSYM)
|
||||||
|
sym = 1;
|
||||||
|
if(st == sf)
|
||||||
|
goto jackpot;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
zwrite(&outbuf, p, sf, st);
|
||||||
|
}
|
||||||
|
firstp = P;
|
||||||
|
lastp = P;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
outhist(Biobuf *b)
|
||||||
|
{
|
||||||
|
Hist *h;
|
||||||
|
char *p, *q, *op, c;
|
||||||
|
Prog pg;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
pg = zprog;
|
||||||
|
pg.as = AHISTORY;
|
||||||
|
c = pathchar();
|
||||||
|
for(h = hist; h != H; h = h->link) {
|
||||||
|
p = h->name;
|
||||||
|
op = 0;
|
||||||
|
/* on windows skip drive specifier in pathname */
|
||||||
|
if(systemtype(Windows) && p && p[1] == ':'){
|
||||||
|
p += 2;
|
||||||
|
c = *p;
|
||||||
|
}
|
||||||
|
if(p && p[0] != c && h->offset == 0 && pathname){
|
||||||
|
/* on windows skip drive specifier in pathname */
|
||||||
|
if(systemtype(Windows) && pathname[1] == ':') {
|
||||||
|
op = p;
|
||||||
|
p = pathname+2;
|
||||||
|
c = *p;
|
||||||
|
} else if(pathname[0] == c){
|
||||||
|
op = p;
|
||||||
|
p = pathname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(p) {
|
||||||
|
q = utfrune(p, c);
|
||||||
|
if(q) {
|
||||||
|
n = q-p;
|
||||||
|
if(n == 0){
|
||||||
|
n = 1; /* leading "/" */
|
||||||
|
*p = '/'; /* don't emit "\" on windows */
|
||||||
|
}
|
||||||
|
q++;
|
||||||
|
} else {
|
||||||
|
n = strlen(p);
|
||||||
|
q = 0;
|
||||||
|
}
|
||||||
|
if(n) {
|
||||||
|
Bputc(b, ANAME);
|
||||||
|
Bputc(b, ANAME>>8);
|
||||||
|
Bputc(b, D_FILE);
|
||||||
|
Bputc(b, 1);
|
||||||
|
Bputc(b, '<');
|
||||||
|
Bwrite(b, p, n);
|
||||||
|
Bputc(b, 0);
|
||||||
|
}
|
||||||
|
p = q;
|
||||||
|
if(p == 0 && op) {
|
||||||
|
p = op;
|
||||||
|
op = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pg.lineno = h->line;
|
||||||
|
pg.to.type = zprog.to.type;
|
||||||
|
pg.to.offset = h->offset;
|
||||||
|
if(h->offset)
|
||||||
|
pg.to.type = D_CONST;
|
||||||
|
|
||||||
|
zwrite(b, &pg, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zname(Biobuf *b, Sym *s, int t)
|
||||||
|
{
|
||||||
|
char *n, bf[8];
|
||||||
|
ulong sig;
|
||||||
|
|
||||||
|
n = s->name;
|
||||||
|
if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
|
||||||
|
sig = sign(s);
|
||||||
|
bf[0] = ASIGNAME;
|
||||||
|
bf[1] = ASIGNAME>>8;
|
||||||
|
bf[2] = sig;
|
||||||
|
bf[3] = sig>>8;
|
||||||
|
bf[4] = sig>>16;
|
||||||
|
bf[5] = sig>>24;
|
||||||
|
bf[6] = t;
|
||||||
|
bf[7] = s->sym;
|
||||||
|
Bwrite(b, bf, 8);
|
||||||
|
s->sig = SIGDONE;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
bf[0] = ANAME;
|
||||||
|
bf[1] = ANAME>>8;
|
||||||
|
bf[2] = t; /* type */
|
||||||
|
bf[3] = s->sym; /* sym */
|
||||||
|
Bwrite(b, bf, 4);
|
||||||
|
}
|
||||||
|
Bwrite(b, n, strlen(n)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
zaddr(char *bp, Adr *a, int s)
|
||||||
|
{
|
||||||
|
long l;
|
||||||
|
Ieee e;
|
||||||
|
|
||||||
|
if(a->type == D_CONST){
|
||||||
|
l = a->offset;
|
||||||
|
if((vlong)l != a->offset)
|
||||||
|
a->type = D_DCONST;
|
||||||
|
}
|
||||||
|
bp[0] = a->type;
|
||||||
|
bp[1] = a->reg;
|
||||||
|
bp[2] = s;
|
||||||
|
bp[3] = a->name;
|
||||||
|
bp += 4;
|
||||||
|
switch(a->type) {
|
||||||
|
default:
|
||||||
|
diag(Z, "unknown type %d in zaddr", a->type);
|
||||||
|
|
||||||
|
case D_NONE:
|
||||||
|
case D_REG:
|
||||||
|
case D_SP:
|
||||||
|
case D_FREG:
|
||||||
|
case D_VREG:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_PAIR:
|
||||||
|
*bp++ = a->offset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_OREG:
|
||||||
|
case D_XPRE:
|
||||||
|
case D_XPOST:
|
||||||
|
case D_CONST:
|
||||||
|
case D_BRANCH:
|
||||||
|
case D_SHIFT:
|
||||||
|
case D_EXTREG:
|
||||||
|
case D_SPR:
|
||||||
|
l = a->offset;
|
||||||
|
bp[0] = l;
|
||||||
|
bp[1] = l>>8;
|
||||||
|
bp[2] = l>>16;
|
||||||
|
bp[3] = l>>24;
|
||||||
|
bp += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_DCONST:
|
||||||
|
l = a->offset;
|
||||||
|
bp[0] = l;
|
||||||
|
bp[1] = l>>8;
|
||||||
|
bp[2] = l>>16;
|
||||||
|
bp[3] = l>>24;
|
||||||
|
bp += 4;
|
||||||
|
l = a->offset>>32;
|
||||||
|
bp[0] = l;
|
||||||
|
bp[1] = l>>8;
|
||||||
|
bp[2] = l>>16;
|
||||||
|
bp[3] = l>>24;
|
||||||
|
bp += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_SCONST:
|
||||||
|
memmove(bp, a->sval, NSNAME);
|
||||||
|
bp += NSNAME;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D_FCONST:
|
||||||
|
ieeedtod(&e, a->dval);
|
||||||
|
l = e.l;
|
||||||
|
bp[0] = l;
|
||||||
|
bp[1] = l>>8;
|
||||||
|
bp[2] = l>>16;
|
||||||
|
bp[3] = l>>24;
|
||||||
|
bp += 4;
|
||||||
|
l = e.h;
|
||||||
|
bp[0] = l;
|
||||||
|
bp[1] = l>>8;
|
||||||
|
bp[2] = l>>16;
|
||||||
|
bp[3] = l>>24;
|
||||||
|
bp += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
align(long i, Type *t, int op)
|
||||||
|
{
|
||||||
|
long o;
|
||||||
|
Type *v;
|
||||||
|
int w;
|
||||||
|
|
||||||
|
o = i;
|
||||||
|
w = 1;
|
||||||
|
switch(op) {
|
||||||
|
default:
|
||||||
|
diag(Z, "unknown align opcode %d", op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Asu2: /* padding at end of a struct */
|
||||||
|
w = SZ_VLONG;
|
||||||
|
if(packflg)
|
||||||
|
w = packflg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Ael1: /* initial align of struct element */
|
||||||
|
for(v=t; v->etype==TARRAY; v=v->link)
|
||||||
|
;
|
||||||
|
w = ewidth[v->etype];
|
||||||
|
if(w <= 0 || w >= SZ_VLONG)
|
||||||
|
w = SZ_VLONG;
|
||||||
|
if(packflg)
|
||||||
|
w = packflg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Ael2: /* width of a struct element */
|
||||||
|
o += t->width;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Aarg0: /* initial passbyptr argument in arg list */
|
||||||
|
if(typesu[t->etype]) {
|
||||||
|
o = align(o, types[TIND], Aarg1);
|
||||||
|
o = align(o, types[TIND], Aarg2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Aarg1: /* initial align of parameter */
|
||||||
|
w = ewidth[t->etype];
|
||||||
|
if(w <= 0 || w >= SZ_VLONG) {
|
||||||
|
w = SZ_VLONG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
w = 1; /* little endian no adjustment */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Aarg2: /* width of a parameter */
|
||||||
|
o += t->width;
|
||||||
|
w = SZ_VLONG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Aaut3: /* total align of automatic */
|
||||||
|
o = align(o, t, Ael2);
|
||||||
|
o = align(o, t, Ael1);
|
||||||
|
w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
o = round(o, w);
|
||||||
|
if(debug['A'])
|
||||||
|
print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
maxround(long max, long v)
|
||||||
|
{
|
||||||
|
v = round(v, SZ_VLONG);
|
||||||
|
if(v > max)
|
||||||
|
return v;
|
||||||
|
return max;
|
||||||
|
}
|
1412
sys/src/cmd/7c/txt.c
Normal file
1412
sys/src/cmd/7c/txt.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue