libqbe/lisc/lisc.h

271 lines
3.3 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 Tmp Tmp;
typedef struct Con Con;
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 {
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,
EAX, /* 32bits */
ECX,
EDX,
ESI,
EDI,
R8D,
R9D,
R10D,
R11D,
EBX,
R12D,
R13D,
R14D,
R15D,
// NReg = R15 - RAX + 1
NReg = 3 /* for test purposes */
2015-07-19 07:03:38 -04:00
};
#define WORD(r) (r + (EAX-RAX))
#define BASE(r) (r >= EAX ? r - (EAX-RAX) : r)
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,
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 {
RTmp,
RCon,
RSlot,
RReg,
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 REG(x) (Ref){RReg, 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 {
Ceq,
Csle,
2015-08-06 13:08:31 -04:00
Cslt,
Csgt, /* mirror opposite cmps! */
2015-08-06 13:08:31 -04:00
Csge,
Cne,
NCmp,
};
2015-08-06 13:08:31 -04:00
#define COP(c) (c==Ceq||c==Cne ? c : NCmp-1 - c)
enum {
OXXX,
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,
OCmp,
OCmp1 = OCmp + NCmp-1,
2015-07-23 18:09:03 -04:00
OStore,
2015-08-08 17:53:48 -04:00
OStores,
OStoreb,
2015-07-23 18:09:03 -04:00
OLoad,
2015-08-08 17:53:48 -04:00
OLoadss,
OLoadus,
OLoadsb,
OLoadub,
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-08-06 16:35:17 -04:00
OXCmpw,
OXCmpl,
OXSet,
OXSet1 = OXSet + NCmp-1,
2015-07-15 02:55:10 -04:00
OLast
2015-06-11 08:49:34 -04:00
};
2015-07-02 16:06:29 -04:00
enum {
JXXX,
2015-06-11 08:49:34 -04:00
JRet,
JJmp,
JJnz,
2015-08-07 14:27:20 -04:00
JXJc,
JXJc1 = JXJc + NCmp-1,
JLast
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 Tmp {
2015-08-02 20:16:18 -04:00
enum {
TUndef,
TWord,
TLong,
2015-08-02 20:16:18 -04:00
} type;
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;
uint spill;
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;
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 dumpts(Bits *, Tmp *, FILE *);
2015-07-22 04:50:52 -04:00
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 *);