libqbe/lisc/lisc.h

228 lines
2.8 KiB
C
Raw Normal View History

2015-06-29 06:56:11 -04:00
#include <assert.h>
2015-07-30 21:32:43 -04:00
#include <inttypes.h>
2015-06-11 08:49:34 -04:00
#include <stdio.h>
2015-07-03 12:16:39 -04:00
#include <stdlib.h>
2015-07-15 18:01:38 -04:00
#include <string.h>
2015-06-11 08:49:34 -04:00
2015-07-03 12:16:39 -04:00
typedef unsigned int uint;
2015-07-17 17:02:09 -04:00
typedef struct Bits Bits;
typedef struct Ref Ref;
typedef struct OpDesc OpDesc;
typedef struct Ins Ins;
typedef struct Phi Phi;
typedef struct Blk Blk;
typedef struct Sym Sym;
typedef struct Cons Cons;
2015-07-17 17:02:09 -04:00
typedef struct Fn Fn;
2015-07-02 16:06:29 -04:00
typedef enum { U, F, T } B3;
2015-07-19 07:03:38 -04:00
enum {
2015-08-01 18:17:06 -04:00
RAX = 1, /* caller-save */
2015-07-19 07:03:38 -04:00
RCX,
RDX,
RSI,
RDI,
R8,
R9,
R10,
R11,
2015-08-01 18:17:06 -04:00
RBX, /* callee-save */
2015-07-19 07:03:38 -04:00
R12,
R13,
R14,
R15,
2015-08-01 18:17:06 -04:00
2015-07-27 14:34:22 -04:00
RBP, /* reserved */
2015-08-01 18:17:06 -04:00
RSP,
// NReg = R15 - RAX + 1
NReg = 3 /* for test purposes */
2015-07-19 07:03:38 -04:00
};
2015-06-11 08:49:34 -04:00
enum {
2015-07-20 17:53:58 -04:00
Tmp0 = 33,
2015-07-15 18:01:38 -04:00
2015-07-02 16:06:29 -04:00
NString = 32,
2015-07-14 06:46:48 -04:00
NPred = 15,
NBlk = 128,
NIns = 256,
2015-07-15 18:01:38 -04:00
BITS = 4,
2015-07-23 18:09:03 -04:00
NBit = 64,
2015-06-11 08:49:34 -04:00
};
2015-07-15 18:01:38 -04:00
struct Bits {
2015-07-20 17:53:58 -04:00
uint64_t t[BITS];
2015-07-15 18:01:38 -04:00
};
#define BGET(b, n) (1&((b).t[n/NBit]>>(n%NBit)))
2015-07-17 17:02:09 -04:00
#define BSET(b, n) ((b).t[n/NBit] |= 1ll<<(n%NBit))
#define BCLR(b, n) ((b).t[n/NBit] &= ~(1ll<<(n%NBit)))
2015-07-15 12:41:51 -04:00
struct Ref {
uint16_t type:2;
uint16_t val:14;
2015-07-15 12:41:51 -04:00
};
2015-07-02 16:06:29 -04:00
enum {
RSym,
RCons,
RSlot,
NRef = (1<<14) - 1
2015-07-02 16:06:29 -04:00
};
2015-07-17 16:54:01 -04:00
#define R (Ref){0, 0}
2015-07-15 15:37:26 -04:00
#define SYM(x) (Ref){RSym, x}
#define CONS(x) (Ref){RCons, x}
#define SLOT(x) (Ref){RSlot, x}
2015-06-11 08:49:34 -04:00
2015-07-17 16:54:01 -04:00
static inline int req(Ref a, Ref b)
2015-07-18 16:41:02 -04:00
{ return a.type == b.type && a.val == b.val; }
2015-07-17 16:54:01 -04:00
static inline int rtype(Ref r)
2015-07-18 16:41:02 -04:00
{ return req(r, R) ? -1 : r.type; }
2015-07-17 16:54:01 -04:00
2015-07-02 16:06:29 -04:00
enum {
2015-07-15 18:01:38 -04:00
OXXX = 0,
2015-07-18 16:41:02 -04:00
/* public instruction */
2015-07-02 16:06:29 -04:00
OAdd,
2015-06-11 08:49:34 -04:00
OSub,
2015-06-29 06:56:11 -04:00
ODiv,
2015-07-18 16:41:02 -04:00
ORem,
2015-07-23 18:09:03 -04:00
OStore,
OLoad,
2015-07-02 16:06:29 -04:00
/* reserved instructions */
2015-07-27 14:57:56 -04:00
ONop,
2015-07-18 16:41:02 -04:00
OCopy,
2015-07-27 14:34:22 -04:00
OSwap,
2015-08-01 18:17:06 -04:00
OSign,
2015-08-01 15:49:02 -04:00
OXDiv,
2015-07-15 02:55:10 -04:00
OLast
2015-06-11 08:49:34 -04:00
};
2015-08-01 18:17:06 -04:00
enum {
CXXX,
CWord,
CLong,
};
2015-07-02 16:06:29 -04:00
enum {
JXXX,
2015-06-11 08:49:34 -04:00
JRet,
JJmp,
2015-07-03 15:19:36 -04:00
JJez,
2015-06-11 08:49:34 -04:00
};
2015-07-15 18:01:38 -04:00
struct OpDesc {
char *name;
int arity;
B3 comm;
2015-07-15 18:01:38 -04:00
};
2015-06-11 08:49:34 -04:00
struct Ins {
2015-07-02 16:06:29 -04:00
short op;
Ref to;
Ref arg[2];
2015-06-11 08:49:34 -04:00
};
struct Phi {
2015-07-02 16:06:29 -04:00
Ref to;
2015-07-14 06:46:48 -04:00
Ref arg[NPred];
Blk *blk[NPred];
uint narg;
Phi *link;
2015-06-11 08:49:34 -04:00
};
struct Blk {
2015-07-14 06:46:48 -04:00
Phi *phi;
Ins *ins;
uint nins;
2015-06-11 08:49:34 -04:00
struct {
2015-07-02 16:06:29 -04:00
short type;
2015-06-11 08:49:34 -04:00
Ref arg;
} jmp;
2015-07-02 16:06:29 -04:00
Blk *s1;
Blk *s2;
Blk *link;
2015-07-02 16:06:29 -04:00
2015-07-22 03:00:03 -04:00
int id;
int visit;
2015-07-14 06:46:48 -04:00
Blk **pred;
uint npred;
Bits in, out, gen;
int nlive;
2015-07-20 17:53:58 -04:00
int loop;
2015-07-10 16:17:55 -04:00
char name[NString];
2015-06-29 06:56:11 -04:00
};
struct Sym {
enum {
SUndef,
SReg,
2015-07-10 16:17:55 -04:00
STmp,
2015-07-02 16:06:29 -04:00
} type;
char name[NString];
2015-08-01 18:17:06 -04:00
int class;
2015-07-20 05:20:20 -04:00
uint ndef, nuse;
2015-07-23 18:09:03 -04:00
uint cost;
uint spill;
2015-07-26 17:21:58 -04:00
int hint;
2015-06-29 06:56:11 -04:00
};
struct Cons {
2015-07-30 21:32:43 -04:00
enum {
CUndef,
CNum,
CAddr,
} type;
char label[NString];
int64_t val;
};
2015-06-29 06:56:11 -04:00
struct Fn {
2015-07-02 16:06:29 -04:00
Blk *start;
2015-06-29 06:56:11 -04:00
Sym *sym;
Cons *cons;
2015-07-10 16:17:55 -04:00
int ntmp;
2015-07-10 13:55:47 -04:00
int nblk;
Blk **rpo;
2015-07-28 22:40:50 -04:00
uint nspill;
2015-06-11 08:49:34 -04:00
};
2015-06-29 06:56:11 -04:00
2015-07-22 04:50:52 -04:00
/* main.c */
extern char debug['Z'+1];
void dumpss(Bits *, Sym *, FILE *);
2015-06-29 06:56:11 -04:00
/* parse.c */
2015-07-15 07:15:40 -04:00
extern OpDesc opdesc[];
2015-07-19 07:03:38 -04:00
void diag(char *);
2015-07-10 11:41:11 -04:00
void *alloc(size_t);
2015-07-25 16:38:02 -04:00
Blk *blocka(void);
2015-06-29 06:56:11 -04:00
Fn *parsefn(FILE *);
2015-07-15 02:55:10 -04:00
void printfn(Fn *, FILE *);
2015-07-10 11:41:11 -04:00
/* ssa.c */
void fillpreds(Fn *);
2015-07-10 13:55:47 -04:00
void fillrpo(Fn *);
2015-07-10 16:17:55 -04:00
void ssafix(Fn *, int);
2015-07-15 18:01:38 -04:00
/* live.c */
void filllive(Fn *);
2015-07-20 17:53:58 -04:00
/* isel.c */
void isel(Fn *);
/* spill.c */
int bcnt(Bits *);
2015-07-20 17:53:58 -04:00
void fillcost(Fn *);
void spill(Fn *);
2015-07-26 17:21:58 -04:00
/* rega.c */
void rega(Fn *);
2015-07-28 22:40:50 -04:00
/* emit.c */
void emitfn(Fn *, FILE *);