add extra functions and clean up makefile and readme
This commit is contained in:
parent
d2f4528797
commit
a5741ed125
6 changed files with 44 additions and 814 deletions
36
Makefile
36
Makefile
|
@ -1,8 +1,12 @@
|
||||||
.POSIX:
|
.POSIX:
|
||||||
.SUFFIXES: .o .c
|
.SUFFIXES: .o .c
|
||||||
|
|
||||||
|
LIBRARY = libqbe.a
|
||||||
|
HEADER = libqbe.h
|
||||||
|
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
BINDIR = $(PREFIX)/bin
|
LIBDIR = $(PREFIX)/lib
|
||||||
|
INCDIR = $(PREFIX)/include
|
||||||
|
|
||||||
COMMOBJ = libqbe.o util.o parse.o abi.o cfg.o mem.o ssa.o alias.o load.o \
|
COMMOBJ = libqbe.o util.o parse.o abi.o cfg.o mem.o ssa.o alias.o load.o \
|
||||||
copy.o fold.o simpl.o live.o spill.o rega.o emit.o
|
copy.o fold.o simpl.o live.o spill.o rega.o emit.o
|
||||||
|
@ -15,7 +19,7 @@ SRCALL = $(OBJ:.o=.c)
|
||||||
|
|
||||||
CC = cc
|
CC = cc
|
||||||
AR = ar
|
AR = ar
|
||||||
CFLAGS = -std=c99 -g -Wall -Wextra -Wpedantic
|
CFLAGS = -std=gnu99 -g -Wall -Wextra -Wpedantic
|
||||||
|
|
||||||
libqbe.a: $(OBJ)
|
libqbe.a: $(OBJ)
|
||||||
$(AR) rcs $@ $(OBJ)
|
$(AR) rcs $@ $(OBJ)
|
||||||
|
@ -23,13 +27,13 @@ libqbe.a: $(OBJ)
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJ): all.h ops.h
|
$(OBJ): qbe/all.h qbe/ops.h
|
||||||
$(AMD64OBJ): amd64/all.h
|
$(AMD64OBJ): amd64/all.h
|
||||||
$(ARM64OBJ): arm64/all.h
|
$(ARM64OBJ): arm64/all.h
|
||||||
$(RV64OBJ): rv64/all.h
|
$(RV64OBJ): rv64/all.h
|
||||||
libqbe.o: config.h
|
libqbe.o: qbe/config.h
|
||||||
|
|
||||||
config.h:
|
qbe/config.h:
|
||||||
@case `uname` in \
|
@case `uname` in \
|
||||||
*Darwin*) \
|
*Darwin*) \
|
||||||
case `uname -m` in \
|
case `uname -m` in \
|
||||||
|
@ -56,27 +60,19 @@ config.h:
|
||||||
;; \
|
;; \
|
||||||
esac > $@
|
esac > $@
|
||||||
|
|
||||||
install: qbe
|
install: $(LIBRARY) $(HEADER)
|
||||||
mkdir -p "$(DESTDIR)$(BINDIR)"
|
mkdir -p "$(DESTDIR)$(LIBDIR)"
|
||||||
install -m755 qbe "$(DESTDIR)$(BINDIR)/qbe"
|
cp "$(LIBRARY)" "$(DESTDIR)$(LIBDIR)/"
|
||||||
|
cp -r "$(HEADER)" "qbe/" "$(DESTDIR)$(INCDIR)/"
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f "$(DESTDIR)$(BINDIR)/qbe"
|
rm -f "$(DESTDIR)$(LIBDIR)/$(LIBRARY)" "$(DESTDIR)$(INCDIR)/$(HEADER)" "$(DESTDIR)$(INCDIR)/qbe"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o */*.o qbe
|
rm -r *.o */*.o
|
||||||
|
|
||||||
clean-gen: clean
|
clean-gen: clean
|
||||||
rm -f config.h
|
rm -f qbe/config.h
|
||||||
|
|
||||||
check: qbe
|
|
||||||
tools/test.sh all
|
|
||||||
|
|
||||||
check-arm64: qbe
|
|
||||||
TARGET=arm64 tools/test.sh all
|
|
||||||
|
|
||||||
check-rv64: qbe
|
|
||||||
TARGET=rv64 tools/test.sh all
|
|
||||||
|
|
||||||
src:
|
src:
|
||||||
@echo $(SRCALL)
|
@echo $(SRCALL)
|
||||||
|
|
8
README
8
README
|
@ -1,9 +1,7 @@
|
||||||
QBE - Backend Compiler http://c9x.me/compile/
|
QBE - Backend Compiler http://c9x.me/compile/
|
||||||
|
|
||||||
doc/ Documentation.
|
I did not create QBE, I simply turned it into a C library.
|
||||||
minic/ An example C frontend for QBE.
|
|
||||||
tools/ Miscellaneous tools (testing).
|
|
||||||
test/ Tests.
|
|
||||||
amd64/
|
amd64/
|
||||||
arm64/
|
arm64/
|
||||||
rv64/ Architecture-specific code.
|
rv64/ Architecture-specific code.
|
||||||
|
@ -15,4 +13,4 @@ The LICENSE file applies to all files distributed.
|
||||||
Invoke make in this directory to create the executable
|
Invoke make in this directory to create the executable
|
||||||
file qbe. Install using 'make install', the standard
|
file qbe. Install using 'make install', the standard
|
||||||
DESTDIR and PREFIX environment variables are supported.
|
DESTDIR and PREFIX environment variables are supported.
|
||||||
Alternatively, you may simply copy the qbe binary manually.
|
Alternatively, you may simply copy the libqbe.a and libqbe.h files manually.
|
||||||
|
|
585
all.h
585
all.h
|
@ -1,585 +0,0 @@
|
||||||
#include <assert.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1]
|
|
||||||
#define die(...) die_(__FILE__, __VA_ARGS__)
|
|
||||||
|
|
||||||
typedef unsigned char uchar;
|
|
||||||
typedef unsigned int uint;
|
|
||||||
typedef unsigned long ulong;
|
|
||||||
typedef unsigned long long bits;
|
|
||||||
|
|
||||||
typedef struct BSet BSet;
|
|
||||||
typedef struct Ref Ref;
|
|
||||||
typedef struct Op Op;
|
|
||||||
typedef struct Ins Ins;
|
|
||||||
typedef struct Phi Phi;
|
|
||||||
typedef struct Blk Blk;
|
|
||||||
typedef struct Use Use;
|
|
||||||
typedef struct Sym Sym;
|
|
||||||
typedef struct Num Num;
|
|
||||||
typedef struct Alias Alias;
|
|
||||||
typedef struct Tmp Tmp;
|
|
||||||
typedef struct Con Con;
|
|
||||||
typedef struct Addr Mem;
|
|
||||||
typedef struct Fn Fn;
|
|
||||||
typedef struct Typ Typ;
|
|
||||||
typedef struct Field Field;
|
|
||||||
typedef struct Dat Dat;
|
|
||||||
typedef struct Lnk Lnk;
|
|
||||||
typedef struct Target Target;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
NString = 80,
|
|
||||||
NIns = 1 << 20,
|
|
||||||
NAlign = 3,
|
|
||||||
NField = 32,
|
|
||||||
NBit = CHAR_BIT * sizeof(bits),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Target {
|
|
||||||
char name[16];
|
|
||||||
char apple;
|
|
||||||
int gpr0; /* first general purpose reg */
|
|
||||||
int ngpr;
|
|
||||||
int fpr0; /* first floating point reg */
|
|
||||||
int nfpr;
|
|
||||||
bits rglob; /* globally live regs (e.g., sp, fp) */
|
|
||||||
int nrglob;
|
|
||||||
int *rsave; /* caller-save */
|
|
||||||
int nrsave[2];
|
|
||||||
bits (*retregs)(Ref, int[2]);
|
|
||||||
bits (*argregs)(Ref, int[2]);
|
|
||||||
int (*memargs)(int);
|
|
||||||
void (*abi0)(Fn *);
|
|
||||||
void (*abi1)(Fn *);
|
|
||||||
void (*isel)(Fn *);
|
|
||||||
void (*emitfn)(Fn *, FILE *);
|
|
||||||
void (*emitfin)(FILE *);
|
|
||||||
char asloc[4];
|
|
||||||
char assym[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BIT(n) ((bits)1 << (n))
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RXX = 0,
|
|
||||||
Tmp0 = NBit, /* first non-reg temporary */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BSet {
|
|
||||||
uint nt;
|
|
||||||
bits *t;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ref {
|
|
||||||
uint type:3;
|
|
||||||
uint val:29;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RTmp,
|
|
||||||
RCon,
|
|
||||||
RInt,
|
|
||||||
RType, /* last kind to come out of the parser */
|
|
||||||
RSlot,
|
|
||||||
RCall,
|
|
||||||
RMem,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define R (Ref){RTmp, 0}
|
|
||||||
#define UNDEF (Ref){RCon, 0} /* represents uninitialized data */
|
|
||||||
#define CON_Z (Ref){RCon, 1}
|
|
||||||
#define TMP(x) (Ref){RTmp, x}
|
|
||||||
#define CON(x) (Ref){RCon, x}
|
|
||||||
#define SLOT(x) (Ref){RSlot, (x)&0x1fffffff}
|
|
||||||
#define TYPE(x) (Ref){RType, x}
|
|
||||||
#define CALL(x) (Ref){RCall, x}
|
|
||||||
#define MEM(x) (Ref){RMem, x}
|
|
||||||
#define INT(x) (Ref){RInt, (x)&0x1fffffff}
|
|
||||||
|
|
||||||
static inline int req(Ref a, Ref b)
|
|
||||||
{
|
|
||||||
return a.type == b.type && a.val == b.val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rtype(Ref r)
|
|
||||||
{
|
|
||||||
if (req(r, R))
|
|
||||||
return -1;
|
|
||||||
return r.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rsval(Ref r)
|
|
||||||
{
|
|
||||||
return ((int)r.val ^ 0x10000000) - 0x10000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CmpI {
|
|
||||||
Cieq,
|
|
||||||
Cine,
|
|
||||||
Cisge,
|
|
||||||
Cisgt,
|
|
||||||
Cisle,
|
|
||||||
Cislt,
|
|
||||||
Ciuge,
|
|
||||||
Ciugt,
|
|
||||||
Ciule,
|
|
||||||
Ciult,
|
|
||||||
NCmpI,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CmpF {
|
|
||||||
Cfeq,
|
|
||||||
Cfge,
|
|
||||||
Cfgt,
|
|
||||||
Cfle,
|
|
||||||
Cflt,
|
|
||||||
Cfne,
|
|
||||||
Cfo,
|
|
||||||
Cfuo,
|
|
||||||
NCmpF,
|
|
||||||
NCmp = NCmpI + NCmpF,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum O {
|
|
||||||
Oxxx,
|
|
||||||
#define O(op, x, y) O##op,
|
|
||||||
#include "ops.h"
|
|
||||||
NOp,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum J {
|
|
||||||
Jxxx,
|
|
||||||
#define JMPS(X) \
|
|
||||||
X(retw) X(retl) X(rets) X(retd) \
|
|
||||||
X(retsb) X(retub) X(retsh) X(retuh) \
|
|
||||||
X(retc) X(ret0) X(jmp) X(jnz) \
|
|
||||||
X(jfieq) X(jfine) X(jfisge) X(jfisgt) \
|
|
||||||
X(jfisle) X(jfislt) X(jfiuge) X(jfiugt) \
|
|
||||||
X(jfiule) X(jfiult) X(jffeq) X(jffge) \
|
|
||||||
X(jffgt) X(jffle) X(jfflt) X(jffne) \
|
|
||||||
X(jffo) X(jffuo) X(hlt)
|
|
||||||
#define X(j) J##j,
|
|
||||||
JMPS(X)
|
|
||||||
#undef X
|
|
||||||
NJmp
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
Ocmpw = Oceqw,
|
|
||||||
Ocmpw1 = Ocultw,
|
|
||||||
Ocmpl = Oceql,
|
|
||||||
Ocmpl1 = Ocultl,
|
|
||||||
Ocmps = Oceqs,
|
|
||||||
Ocmps1 = Ocuos,
|
|
||||||
Ocmpd = Oceqd,
|
|
||||||
Ocmpd1 = Ocuod,
|
|
||||||
Oalloc = Oalloc4,
|
|
||||||
Oalloc1 = Oalloc16,
|
|
||||||
Oflag = Oflagieq,
|
|
||||||
Oflag1 = Oflagfuo,
|
|
||||||
NPubOp = Onop,
|
|
||||||
Jjf = Jjfieq,
|
|
||||||
Jjf1 = Jjffuo,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define INRANGE(x, l, u) ((unsigned)(x) - l <= u - l) /* linear in x */
|
|
||||||
#define isstore(o) INRANGE(o, Ostoreb, Ostored)
|
|
||||||
#define isload(o) INRANGE(o, Oloadsb, Oload)
|
|
||||||
#define isext(o) INRANGE(o, Oextsb, Oextuw)
|
|
||||||
#define ispar(o) INRANGE(o, Opar, Opare)
|
|
||||||
#define isarg(o) INRANGE(o, Oarg, Oargv)
|
|
||||||
#define isret(j) INRANGE(j, Jretw, Jret0)
|
|
||||||
#define isparbh(o) INRANGE(o, Oparsb, Oparuh)
|
|
||||||
#define isargbh(o) INRANGE(o, Oargsb, Oarguh)
|
|
||||||
#define isretbh(j) INRANGE(j, Jretsb, Jretuh)
|
|
||||||
|
|
||||||
enum {
|
|
||||||
Kx = -1, /* "top" class (see usecheck() and clsmerge()) */
|
|
||||||
Kw,
|
|
||||||
Kl,
|
|
||||||
Ks,
|
|
||||||
Kd
|
|
||||||
};
|
|
||||||
|
|
||||||
#define KWIDE(k) ((k)&1)
|
|
||||||
#define KBASE(k) ((k)>>1)
|
|
||||||
|
|
||||||
struct Op {
|
|
||||||
char *name;
|
|
||||||
short argcls[2][4];
|
|
||||||
uint canfold:1;
|
|
||||||
uint hasid:1;
|
|
||||||
uint idval:1; /* identity value 0/1 */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ins {
|
|
||||||
uint op:30;
|
|
||||||
uint cls:2;
|
|
||||||
Ref to;
|
|
||||||
Ref arg[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Phi {
|
|
||||||
Ref to;
|
|
||||||
Ref *arg;
|
|
||||||
Blk **blk;
|
|
||||||
uint narg;
|
|
||||||
int cls;
|
|
||||||
Phi *link;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Blk {
|
|
||||||
Phi *phi;
|
|
||||||
Ins *ins;
|
|
||||||
uint nins;
|
|
||||||
struct {
|
|
||||||
short type;
|
|
||||||
Ref arg;
|
|
||||||
} jmp;
|
|
||||||
Blk *s1;
|
|
||||||
Blk *s2;
|
|
||||||
Blk *link;
|
|
||||||
|
|
||||||
uint id;
|
|
||||||
uint visit;
|
|
||||||
|
|
||||||
Blk *idom;
|
|
||||||
Blk *dom, *dlink;
|
|
||||||
Blk **fron;
|
|
||||||
uint nfron;
|
|
||||||
|
|
||||||
Blk **pred;
|
|
||||||
uint npred;
|
|
||||||
BSet in[1], out[1], gen[1];
|
|
||||||
int nlive[2];
|
|
||||||
int loop;
|
|
||||||
char name[NString];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Use {
|
|
||||||
enum {
|
|
||||||
UXXX,
|
|
||||||
UPhi,
|
|
||||||
UIns,
|
|
||||||
UJmp,
|
|
||||||
} type;
|
|
||||||
uint bid;
|
|
||||||
union {
|
|
||||||
Ins *ins;
|
|
||||||
Phi *phi;
|
|
||||||
} u;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Sym {
|
|
||||||
enum {
|
|
||||||
SGlo,
|
|
||||||
SThr,
|
|
||||||
} type;
|
|
||||||
uint32_t id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Num {
|
|
||||||
uchar n;
|
|
||||||
uchar nl, nr;
|
|
||||||
Ref l, r;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
NoAlias,
|
|
||||||
MayAlias,
|
|
||||||
MustAlias
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Alias {
|
|
||||||
enum {
|
|
||||||
ABot = 0,
|
|
||||||
ALoc = 1, /* stack local */
|
|
||||||
ACon = 2,
|
|
||||||
AEsc = 3, /* stack escaping */
|
|
||||||
ASym = 4,
|
|
||||||
AUnk = 6,
|
|
||||||
#define astack(t) ((t) & 1)
|
|
||||||
} type;
|
|
||||||
int base;
|
|
||||||
int64_t offset;
|
|
||||||
union {
|
|
||||||
Sym sym;
|
|
||||||
struct {
|
|
||||||
int sz; /* -1 if > NBit */
|
|
||||||
bits m;
|
|
||||||
} loc;
|
|
||||||
} u;
|
|
||||||
Alias *slot;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Tmp {
|
|
||||||
char name[NString];
|
|
||||||
Ins *def;
|
|
||||||
Use *use;
|
|
||||||
uint ndef, nuse;
|
|
||||||
uint bid; /* id of a defining block */
|
|
||||||
uint cost;
|
|
||||||
int slot; /* -1 for unset */
|
|
||||||
short cls;
|
|
||||||
struct {
|
|
||||||
int r; /* register or -1 */
|
|
||||||
int w; /* weight */
|
|
||||||
bits m; /* avoid these registers */
|
|
||||||
} hint;
|
|
||||||
int phi;
|
|
||||||
Alias alias;
|
|
||||||
enum {
|
|
||||||
WFull,
|
|
||||||
Wsb, /* must match Oload/Oext order */
|
|
||||||
Wub,
|
|
||||||
Wsh,
|
|
||||||
Wuh,
|
|
||||||
Wsw,
|
|
||||||
Wuw
|
|
||||||
} width;
|
|
||||||
int visit;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Con {
|
|
||||||
enum {
|
|
||||||
CUndef,
|
|
||||||
CBits,
|
|
||||||
CAddr,
|
|
||||||
} type;
|
|
||||||
Sym sym;
|
|
||||||
union {
|
|
||||||
int64_t i;
|
|
||||||
double d;
|
|
||||||
float s;
|
|
||||||
} bits;
|
|
||||||
char flt; /* 1 to print as s, 2 to print as d */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct Addr Addr;
|
|
||||||
|
|
||||||
struct Addr { /* amd64 addressing */
|
|
||||||
Con offset;
|
|
||||||
Ref base;
|
|
||||||
Ref index;
|
|
||||||
int scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Lnk {
|
|
||||||
char export;
|
|
||||||
char thread;
|
|
||||||
char common;
|
|
||||||
char align;
|
|
||||||
char *sec;
|
|
||||||
char *secf;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Fn {
|
|
||||||
Blk *start;
|
|
||||||
Tmp *tmp;
|
|
||||||
Con *con;
|
|
||||||
Mem *mem;
|
|
||||||
int ntmp;
|
|
||||||
int ncon;
|
|
||||||
int nmem;
|
|
||||||
uint nblk;
|
|
||||||
int retty; /* index in typ[], -1 if no aggregate return */
|
|
||||||
Ref retr;
|
|
||||||
Blk **rpo;
|
|
||||||
bits reg;
|
|
||||||
int slot;
|
|
||||||
char vararg;
|
|
||||||
char dynalloc;
|
|
||||||
char name[NString];
|
|
||||||
Lnk lnk;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Typ {
|
|
||||||
char name[NString];
|
|
||||||
char isdark;
|
|
||||||
char isunion;
|
|
||||||
int align;
|
|
||||||
uint64_t size;
|
|
||||||
uint nunion;
|
|
||||||
struct Field {
|
|
||||||
enum {
|
|
||||||
FEnd,
|
|
||||||
Fb,
|
|
||||||
Fh,
|
|
||||||
Fw,
|
|
||||||
Fl,
|
|
||||||
Fs,
|
|
||||||
Fd,
|
|
||||||
FPad,
|
|
||||||
FTyp,
|
|
||||||
} type;
|
|
||||||
uint len; /* or index in typ[] for FTyp */
|
|
||||||
} (*fields)[NField+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Dat {
|
|
||||||
enum {
|
|
||||||
DStart,
|
|
||||||
DEnd,
|
|
||||||
DB,
|
|
||||||
DH,
|
|
||||||
DW,
|
|
||||||
DL,
|
|
||||||
DZ
|
|
||||||
} type;
|
|
||||||
char *name;
|
|
||||||
Lnk *lnk;
|
|
||||||
union {
|
|
||||||
int64_t num;
|
|
||||||
double fltd;
|
|
||||||
float flts;
|
|
||||||
char *str;
|
|
||||||
struct {
|
|
||||||
char *name;
|
|
||||||
int64_t off;
|
|
||||||
} ref;
|
|
||||||
} u;
|
|
||||||
char isref;
|
|
||||||
char isstr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* main.c */
|
|
||||||
extern Target T;
|
|
||||||
extern char debug['Z'+1];
|
|
||||||
|
|
||||||
/* util.c */
|
|
||||||
typedef enum {
|
|
||||||
PHeap, /* free() necessary */
|
|
||||||
PFn, /* discarded after processing the function */
|
|
||||||
} Pool;
|
|
||||||
|
|
||||||
extern Typ *typ;
|
|
||||||
extern Ins insb[NIns], *curi;
|
|
||||||
uint32_t hash(char *);
|
|
||||||
void die_(char *, char *, ...) __attribute__((noreturn));
|
|
||||||
void *emalloc(size_t);
|
|
||||||
void *alloc(size_t);
|
|
||||||
void freeall(void);
|
|
||||||
void *vnew(ulong, size_t, Pool);
|
|
||||||
void vfree(void *);
|
|
||||||
void vgrow(void *, ulong);
|
|
||||||
void strf(char[NString], char *, ...);
|
|
||||||
uint32_t intern(char *);
|
|
||||||
char *str(uint32_t);
|
|
||||||
int argcls(Ins *, int);
|
|
||||||
int isreg(Ref);
|
|
||||||
int iscmp(int, int *, int *);
|
|
||||||
void emit(int, int, Ref, Ref, Ref);
|
|
||||||
void emiti(Ins);
|
|
||||||
void idup(Ins **, Ins *, ulong);
|
|
||||||
Ins *icpy(Ins *, Ins *, ulong);
|
|
||||||
int cmpop(int);
|
|
||||||
int cmpneg(int);
|
|
||||||
int clsmerge(short *, short);
|
|
||||||
int phicls(int, Tmp *);
|
|
||||||
Ref newtmp(char *, int, Fn *);
|
|
||||||
void chuse(Ref, int, Fn *);
|
|
||||||
int symeq(Sym, Sym);
|
|
||||||
Ref newcon(Con *, Fn *);
|
|
||||||
Ref getcon(int64_t, Fn *);
|
|
||||||
int addcon(Con *, Con *, int);
|
|
||||||
void salloc(Ref, Ref, Fn *);
|
|
||||||
void dumpts(BSet *, Tmp *, FILE *);
|
|
||||||
void runmatch(uchar *, Num *, Ref, Ref *);
|
|
||||||
|
|
||||||
void bsinit(BSet *, uint);
|
|
||||||
void bszero(BSet *);
|
|
||||||
uint bscount(BSet *);
|
|
||||||
void bsset(BSet *, uint);
|
|
||||||
void bsclr(BSet *, uint);
|
|
||||||
void bscopy(BSet *, BSet *);
|
|
||||||
void bsunion(BSet *, BSet *);
|
|
||||||
void bsinter(BSet *, BSet *);
|
|
||||||
void bsdiff(BSet *, BSet *);
|
|
||||||
int bsequal(BSet *, BSet *);
|
|
||||||
int bsiter(BSet *, int *);
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
bshas(BSet *bs, uint elt)
|
|
||||||
{
|
|
||||||
assert(elt < bs->nt * NBit);
|
|
||||||
return (bs->t[elt/NBit] & BIT(elt%NBit)) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse.c */
|
|
||||||
extern Op optab[NOp];
|
|
||||||
void parse(FILE *, char *, void (char *), void (Dat *), void (Fn *));
|
|
||||||
void printfn(Fn *, FILE *);
|
|
||||||
void printref(Ref, Fn *, FILE *);
|
|
||||||
void err(char *, ...) __attribute__((noreturn));
|
|
||||||
|
|
||||||
/* abi.c */
|
|
||||||
void elimsb(Fn *);
|
|
||||||
|
|
||||||
/* cfg.c */
|
|
||||||
Blk *newblk(void);
|
|
||||||
void edgedel(Blk *, Blk **);
|
|
||||||
void fillpreds(Fn *);
|
|
||||||
void fillrpo(Fn *);
|
|
||||||
void filldom(Fn *);
|
|
||||||
int sdom(Blk *, Blk *);
|
|
||||||
int dom(Blk *, Blk *);
|
|
||||||
void fillfron(Fn *);
|
|
||||||
void loopiter(Fn *, void (*)(Blk *, Blk *));
|
|
||||||
void fillloop(Fn *);
|
|
||||||
void simpljmp(Fn *);
|
|
||||||
|
|
||||||
/* mem.c */
|
|
||||||
void promote(Fn *);
|
|
||||||
void coalesce(Fn *);
|
|
||||||
|
|
||||||
/* alias.c */
|
|
||||||
void fillalias(Fn *);
|
|
||||||
void getalias(Alias *, Ref, Fn *);
|
|
||||||
int alias(Ref, int, int, Ref, int, int *, Fn *);
|
|
||||||
int escapes(Ref, Fn *);
|
|
||||||
|
|
||||||
/* load.c */
|
|
||||||
int loadsz(Ins *);
|
|
||||||
int storesz(Ins *);
|
|
||||||
void loadopt(Fn *);
|
|
||||||
|
|
||||||
/* ssa.c */
|
|
||||||
void filluse(Fn *);
|
|
||||||
void ssa(Fn *);
|
|
||||||
void ssacheck(Fn *);
|
|
||||||
|
|
||||||
/* copy.c */
|
|
||||||
void copy(Fn *);
|
|
||||||
|
|
||||||
/* fold.c */
|
|
||||||
void fold(Fn *);
|
|
||||||
|
|
||||||
/* simpl.c */
|
|
||||||
void simpl(Fn *);
|
|
||||||
|
|
||||||
/* live.c */
|
|
||||||
void liveon(BSet *, Blk *, Blk *);
|
|
||||||
void filllive(Fn *);
|
|
||||||
|
|
||||||
/* spill.c */
|
|
||||||
void fillcost(Fn *);
|
|
||||||
void spill(Fn *);
|
|
||||||
|
|
||||||
/* rega.c */
|
|
||||||
void rega(Fn *);
|
|
||||||
|
|
||||||
/* emit.c */
|
|
||||||
void emitfnlnk(char *, Lnk *, FILE *);
|
|
||||||
void emitdat(Dat *, FILE *);
|
|
||||||
void emitdbgfile(char *, FILE *);
|
|
||||||
void emitdbgloc(uint, uint, FILE *);
|
|
||||||
int stashbits(void *, int);
|
|
||||||
void elf_emitfnfin(char *, FILE *);
|
|
||||||
void elf_emitfin(FILE *);
|
|
||||||
void macho_emitfin(FILE *);
|
|
1
all.h
Symbolic link
1
all.h
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
qbe/all.h
|
20
libqbe.c
20
libqbe.c
|
@ -1,5 +1,4 @@
|
||||||
#include "libqbe.h"
|
#include "libqbe.h"
|
||||||
#include <ctype.h>
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -100,7 +99,7 @@ dbgfile(char *fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
qbe_emit(Target target, const char* ssa)
|
qbe_gen(Target target, const char* ssa)
|
||||||
{
|
{
|
||||||
T = target;
|
T = target;
|
||||||
FILE *inf = tmpfile();
|
FILE *inf = tmpfile();
|
||||||
|
@ -127,3 +126,20 @@ qbe_emit(Target target, const char* ssa)
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qbe_emit(const char* filename, const char* assembly) {
|
||||||
|
char cc[255];
|
||||||
|
snprintf(cc, 255, "cc -x assembler -o %s -", filename);
|
||||||
|
|
||||||
|
FILE* cc_pipe = popen(cc, "w");
|
||||||
|
if(fputs(assembly, cc_pipe) == EOF) {
|
||||||
|
perror("fputs");
|
||||||
|
}
|
||||||
|
pclose(cc_pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qbe_gen_and_emit(Target target, const char* filename, const char* ssa) {
|
||||||
|
qbe_emit(filename, qbe_gen(target, ssa));
|
||||||
|
}
|
||||||
|
|
8
libqbe.h
8
libqbe.h
|
@ -1,5 +1,5 @@
|
||||||
#include "all.h"
|
#include "qbe/all.h"
|
||||||
#include "config.h"
|
#include "qbe/config.h"
|
||||||
|
|
||||||
#ifndef __LIBQBE_H__
|
#ifndef __LIBQBE_H__
|
||||||
#define __LIBQBE_H__
|
#define __LIBQBE_H__
|
||||||
|
@ -10,6 +10,8 @@ extern Target T_arm64;
|
||||||
extern Target T_arm64_apple;
|
extern Target T_arm64_apple;
|
||||||
extern Target T_rv64;
|
extern Target T_rv64;
|
||||||
|
|
||||||
const char* qbe_emit(Target target, const char* ssa);
|
const char* qbe_gen(Target target, const char* ssa);
|
||||||
|
void qbe_emit(const char* filename, const char* assembly);
|
||||||
|
void qbe_gen_and_emit(Target target, const char* filename, const char* ssa);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
199
ops.h
199
ops.h
|
@ -1,199 +0,0 @@
|
||||||
#ifndef X /* amd64 */
|
|
||||||
#define X(NMemArgs, SetsZeroFlag, LeavesFlags)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef V /* riscv64 */
|
|
||||||
#define V(Imm)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef P
|
|
||||||
#define P(CanFold, HasId, IdVal)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define T(a,b,c,d,e,f,g,h) { \
|
|
||||||
{[Kw]=K##a, [Kl]=K##b, [Ks]=K##c, [Kd]=K##d}, \
|
|
||||||
{[Kw]=K##e, [Kl]=K##f, [Ks]=K##g, [Kd]=K##h} \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*********************/
|
|
||||||
/* PUBLIC OPERATIONS */
|
|
||||||
/*********************/
|
|
||||||
|
|
||||||
/* Arithmetic and Bits */
|
|
||||||
O(add, T(w,l,s,d, w,l,s,d), P(1,1,0)) X(2,1,0) V(1)
|
|
||||||
O(sub, T(w,l,s,d, w,l,s,d), P(1,1,0)) X(2,1,0) V(0)
|
|
||||||
O(neg, T(w,l,s,d, x,x,x,x), P(1,0,0)) X(1,1,0) V(0)
|
|
||||||
O(div, T(w,l,s,d, w,l,s,d), P(1,1,1)) X(0,0,0) V(0)
|
|
||||||
O(rem, T(w,l,e,e, w,l,e,e), P(1,0,0)) X(0,0,0) V(0)
|
|
||||||
O(udiv, T(w,l,e,e, w,l,e,e), P(1,1,1)) X(0,0,0) V(0)
|
|
||||||
O(urem, T(w,l,e,e, w,l,e,e), P(1,0,0)) X(0,0,0) V(0)
|
|
||||||
O(mul, T(w,l,s,d, w,l,s,d), P(1,1,1)) X(2,0,0) V(0)
|
|
||||||
O(and, T(w,l,e,e, w,l,e,e), P(1,0,0)) X(2,1,0) V(1)
|
|
||||||
O(or, T(w,l,e,e, w,l,e,e), P(1,1,0)) X(2,1,0) V(1)
|
|
||||||
O(xor, T(w,l,e,e, w,l,e,e), P(1,1,0)) X(2,1,0) V(1)
|
|
||||||
O(sar, T(w,l,e,e, w,w,e,e), P(1,1,0)) X(1,1,0) V(1)
|
|
||||||
O(shr, T(w,l,e,e, w,w,e,e), P(1,1,0)) X(1,1,0) V(1)
|
|
||||||
O(shl, T(w,l,e,e, w,w,e,e), P(1,1,0)) X(1,1,0) V(1)
|
|
||||||
|
|
||||||
/* Comparisons */
|
|
||||||
O(ceqw, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cnew, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(csgew, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(csgtw, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cslew, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(csltw, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(1)
|
|
||||||
O(cugew, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cugtw, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(culew, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cultw, T(w,w,e,e, w,w,e,e), P(1,0,0)) X(0,1,0) V(1)
|
|
||||||
|
|
||||||
O(ceql, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cnel, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(csgel, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(csgtl, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cslel, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(csltl, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(1)
|
|
||||||
O(cugel, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cugtl, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(culel, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cultl, T(l,l,e,e, l,l,e,e), P(1,0,0)) X(0,1,0) V(1)
|
|
||||||
|
|
||||||
O(ceqs, T(s,s,e,e, s,s,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cges, T(s,s,e,e, s,s,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cgts, T(s,s,e,e, s,s,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cles, T(s,s,e,e, s,s,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(clts, T(s,s,e,e, s,s,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cnes, T(s,s,e,e, s,s,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cos, T(s,s,e,e, s,s,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cuos, T(s,s,e,e, s,s,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
|
|
||||||
O(ceqd, T(d,d,e,e, d,d,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cged, T(d,d,e,e, d,d,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cgtd, T(d,d,e,e, d,d,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cled, T(d,d,e,e, d,d,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cltd, T(d,d,e,e, d,d,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cned, T(d,d,e,e, d,d,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cod, T(d,d,e,e, d,d,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
O(cuod, T(d,d,e,e, d,d,e,e), P(1,0,0)) X(0,1,0) V(0)
|
|
||||||
|
|
||||||
/* Memory */
|
|
||||||
O(storeb, T(w,e,e,e, m,e,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(storeh, T(w,e,e,e, m,e,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(storew, T(w,e,e,e, m,e,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(storel, T(l,e,e,e, m,e,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(stores, T(s,e,e,e, m,e,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(stored, T(d,e,e,e, m,e,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
|
|
||||||
O(loadsb, T(m,m,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(loadub, T(m,m,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(loadsh, T(m,m,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(loaduh, T(m,m,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(loadsw, T(m,m,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(loaduw, T(m,m,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(load, T(m,m,m,m, x,x,x,x), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
|
|
||||||
/* Extensions and Truncations */
|
|
||||||
O(extsb, T(w,w,e,e, x,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(extub, T(w,w,e,e, x,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(extsh, T(w,w,e,e, x,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(extuh, T(w,w,e,e, x,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(extsw, T(e,w,e,e, e,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(extuw, T(e,w,e,e, e,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
|
|
||||||
O(exts, T(e,e,e,s, e,e,e,x), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(truncd, T(e,e,d,e, e,e,x,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(stosi, T(s,s,e,e, x,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(stoui, T(s,s,e,e, x,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(dtosi, T(d,d,e,e, x,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(dtoui, T(d,d,e,e, x,x,e,e), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(swtof, T(e,e,w,w, e,e,x,x), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(uwtof, T(e,e,w,w, e,e,x,x), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(sltof, T(e,e,l,l, e,e,x,x), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(ultof, T(e,e,l,l, e,e,x,x), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
O(cast, T(s,d,w,l, x,x,x,x), P(1,0,0)) X(0,0,1) V(0)
|
|
||||||
|
|
||||||
/* Stack Allocation */
|
|
||||||
O(alloc4, T(e,l,e,e, e,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(alloc8, T(e,l,e,e, e,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(alloc16, T(e,l,e,e, e,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
|
|
||||||
/* Variadic Function Helpers */
|
|
||||||
O(vaarg, T(m,m,m,m, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(vastart, T(m,e,e,e, x,e,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
|
|
||||||
O(copy, T(w,l,s,d, x,x,x,x), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
|
|
||||||
/* Debug */
|
|
||||||
O(dbgloc, T(w,e,e,e, w,e,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
|
|
||||||
/****************************************/
|
|
||||||
/* INTERNAL OPERATIONS (keep nop first) */
|
|
||||||
/****************************************/
|
|
||||||
|
|
||||||
/* Miscellaneous and Architecture-Specific Operations */
|
|
||||||
O(nop, T(x,x,x,x, x,x,x,x), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(addr, T(m,m,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(blit0, T(m,e,e,e, m,e,e,e), P(0,0,0)) X(0,1,0) V(0)
|
|
||||||
O(blit1, T(w,e,e,e, x,e,e,e), P(0,0,0)) X(0,1,0) V(0)
|
|
||||||
O(swap, T(w,l,s,d, w,l,s,d), P(0,0,0)) X(1,0,0) V(0)
|
|
||||||
O(sign, T(w,l,e,e, x,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(salloc, T(e,l,e,e, e,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(xidiv, T(w,l,e,e, x,x,e,e), P(0,0,0)) X(1,0,0) V(0)
|
|
||||||
O(xdiv, T(w,l,e,e, x,x,e,e), P(0,0,0)) X(1,0,0) V(0)
|
|
||||||
O(xcmp, T(w,l,s,d, w,l,s,d), P(0,0,0)) X(1,1,0) V(0)
|
|
||||||
O(xtest, T(w,l,e,e, w,l,e,e), P(0,0,0)) X(1,1,0) V(0)
|
|
||||||
O(acmp, T(w,l,e,e, w,l,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(acmn, T(w,l,e,e, w,l,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(afcmp, T(e,e,s,d, e,e,s,d), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(reqz, T(w,l,e,e, x,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(rnez, T(w,l,e,e, x,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
|
|
||||||
/* Arguments, Parameters, and Calls */
|
|
||||||
O(par, T(x,x,x,x, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(parsb, T(x,x,x,x, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(parub, T(x,x,x,x, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(parsh, T(x,x,x,x, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(paruh, T(x,x,x,x, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(parc, T(e,x,e,e, e,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(pare, T(e,x,e,e, e,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(arg, T(w,l,s,d, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(argsb, T(w,e,e,e, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(argub, T(w,e,e,e, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(argsh, T(w,e,e,e, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(arguh, T(w,e,e,e, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(argc, T(e,x,e,e, e,l,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(arge, T(e,l,e,e, e,x,e,e), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(argv, T(x,x,x,x, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
O(call, T(m,m,m,m, x,x,x,x), P(0,0,0)) X(0,0,0) V(0)
|
|
||||||
|
|
||||||
/* Flags Setting */
|
|
||||||
O(flagieq, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagine, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagisge, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagisgt, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagisle, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagislt, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagiuge, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagiugt, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagiule, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagiult, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagfeq, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagfge, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagfgt, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagfle, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagflt, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagfne, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagfo, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
O(flagfuo, T(x,x,e,e, x,x,e,e), P(0,0,0)) X(0,0,1) V(0)
|
|
||||||
|
|
||||||
|
|
||||||
#undef T
|
|
||||||
#undef X
|
|
||||||
#undef V
|
|
||||||
#undef O
|
|
||||||
|
|
||||||
/*
|
|
||||||
| column -t -o ' '
|
|
||||||
*/
|
|
1
ops.h
Symbolic link
1
ops.h
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
qbe/ops.h
|
Loading…
Add table
Reference in a new issue