libqbe/lisc/lisc.h

308 lines
4 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-09-20 17:46:17 -04:00
typedef unsigned long long ulong;
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 Tmp Tmp;
typedef struct Con Con;
2015-07-17 17:02:09 -04:00
typedef struct Fn Fn;
2015-09-08 16:16:08 -04:00
typedef struct Typ Typ;
2015-07-02 16:06:29 -04:00
typedef enum { U, F, T } B3;
enum Reg {
RXX,
RAX, /* 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,
Tmp0, /* first non-reg temporary */
NReg = R12 - RAX + 1,
NRSave = 9,
2015-09-20 17:46:17 -04:00
NRClob = 5,
2015-07-19 07:03:38 -04:00
};
2015-06-11 08:49:34 -04:00
enum {
2015-07-02 16:06:29 -04:00
NString = 32,
2015-07-14 06:46:48 -04:00
NPred = 15,
NBlk = 128,
NIns = 256,
NAlign = 3,
NSeg = 32,
2015-09-10 22:55:03 -04:00
NTyp = 128,
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-09-20 17:46:17 -04:00
ulong t[BITS];
2015-07-15 18:01:38 -04:00
};
2015-09-20 17:46:17 -04:00
#define BIT(n) (1ull << (n))
2015-07-15 18:01:38 -04:00
#define BGET(b, n) (1&((b).t[n/NBit]>>(n%NBit)))
2015-09-20 17:46:17 -04:00
#define BSET(b, n) ((b).t[n/NBit] |= BIT(n%NBit))
#define BCLR(b, n) ((b).t[n/NBit] &= ~BIT(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 {
RTmp,
RCon,
RSlot,
RAlt,
RCallm = 0x1000,
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}
#define TMP(x) (Ref){RTmp, x}
#define CON(x) (Ref){RCon, x}
2015-08-07 14:27:20 -04:00
#define CON_Z CON(0) /* reserved zero constant */
#define SLOT(x) (Ref){RSlot, x}
#define TYP(x) (Ref){RAlt, x}
2015-09-16 22:45:01 -04:00
#define CALL(x) (Ref){RAlt, (x)|RCallm}
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-08-24 12:39:55 -04:00
static inline int isreg(Ref r)
{ return rtype(r) == RTmp && r.val < Tmp0; }
2015-07-17 16:54:01 -04:00
2015-09-08 16:16:08 -04:00
#define CMPS(X) \
X(eq) X(sle) X(slt) \
X(sgt) X(sge) X(ne) /* mirror opposite cmps! */
enum Cmp {
2015-09-08 16:16:08 -04:00
#define C(c) C##c,
CMPS(C)
#undef C
2015-08-19 15:10:07 -04:00
NCmp
};
2015-08-06 13:08:31 -04:00
#define COP(c) (c==Ceq||c==Cne ? c : NCmp-1 - c)
enum Op {
OXXX,
2015-08-08 18:32:03 -04:00
2015-08-09 17:55:05 -04:00
/* public instructions */
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-08-16 14:19:54 -04:00
OMul,
2015-08-12 15:25:53 -04:00
OAnd,
2015-08-17 19:00:51 -04:00
OSext,
OZext,
OCmp,
OCmp1 = OCmp + NCmp-1,
2015-08-11 16:26:12 -04:00
OStorel,
OStorew,
2015-08-08 17:53:48 -04:00
OStores,
OStoreb,
2015-07-23 18:09:03 -04:00
OLoad,
OLoadsh,
OLoaduh,
2015-08-08 17:53:48 -04:00
OLoadsb,
OLoadub,
2015-08-12 15:25:53 -04:00
OAlloc,
OAlloc1 = OAlloc + NAlign-1,
2015-08-16 11:34:52 -04:00
OCopy,
2015-08-08 18:32:03 -04:00
NPubOp,
2015-09-09 18:33:00 -04:00
/* function instructions */
2015-09-17 19:29:49 -04:00
OPar = NPubOp,
OParc,
OArg,
2015-09-09 18:33:00 -04:00
OArgc,
OCall,
2015-08-08 18:32:03 -04:00
/* reserved instructions */
2015-09-09 18:33:00 -04:00
ONop,
2015-08-16 11:34:52 -04:00
OAddr,
2015-07-27 14:34:22 -04:00
OSwap,
2015-08-01 18:17:06 -04:00
OSign,
2015-09-10 22:55:03 -04:00
OSAlloc,
OXPush,
2015-08-01 15:49:02 -04:00
OXDiv,
2015-08-24 12:39:55 -04:00
OXCmp,
OXSet,
OXSet1 = OXSet + NCmp-1,
2015-08-24 12:39:55 -04:00
OXTest,
2015-08-08 18:32:03 -04:00
NOp
2015-06-11 08:49:34 -04:00
};
enum Jmp {
2015-07-02 16:06:29 -04:00
JXXX,
2015-09-22 16:52:48 -04:00
JRet0,
JRetw,
JRetl,
JRetc,
2015-06-11 08:49:34 -04:00
JJmp,
JJnz,
2015-08-07 14:27:20 -04:00
JXJc,
JXJc1 = JXJc + NCmp-1,
2015-08-09 17:55:05 -04:00
NJmp
2015-06-11 08:49:34 -04:00
};
2015-07-15 18:01:38 -04:00
struct OpDesc {
char *name;
int nmem;
2015-07-15 18:01:38 -04:00
};
2015-06-11 08:49:34 -04:00
struct Ins {
2015-08-24 12:39:55 -04:00
uint16_t op:15;
uint16_t wide:1;
2015-07-02 16:06:29 -04:00
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;
2015-08-24 12:39:55 -04:00
uint wide;
2015-07-14 06:46:48 -04:00
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 Tmp {
2015-07-02 16:06:29 -04:00
char name[NString];
2015-07-20 05:20:20 -04:00
uint ndef, nuse;
2015-07-23 18:09:03 -04:00
uint cost;
2015-08-24 12:39:55 -04:00
short spill;
short wide;
2015-07-26 17:21:58 -04:00
int hint;
2015-06-29 06:56:11 -04:00
};
struct Con {
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;
Tmp *tmp;
Con *con;
int ntmp;
int ncon;
2015-07-10 13:55:47 -04:00
int nblk;
2015-09-25 11:33:50 -04:00
int retty;
2015-07-10 13:55:47 -04:00
Blk **rpo;
2015-09-20 17:46:17 -04:00
ulong reg;
int svec[NAlign];
char name[NString];
};
2015-09-08 16:16:08 -04:00
struct Typ {
2015-09-07 23:06:13 -04:00
char name[NString];
int dark;
2015-09-07 23:08:27 -04:00
uint size;
int align;
struct {
uint flt:1;
uint len:31;
2015-09-10 22:55:03 -04:00
} seg[NSeg+1];
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 dumpts(Bits *, Tmp *, FILE *);
2015-07-22 04:50:52 -04:00
2015-06-29 06:56:11 -04:00
/* parse.c */
2015-09-10 22:55:03 -04:00
extern Typ typ[NTyp];
extern OpDesc opdesc[NOp];
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);
Fn *parse(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 */
extern int rsave[NRSave];
2015-09-20 17:46:17 -04:00
extern int rclob[NRClob];
ulong calldef(Ins, int *);
ulong calluse(Ins, int *);
ulong callclb(Ins, int *);
int slota(int, int, int *);
2015-07-20 17:53:58 -04:00
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 *);