From dfda5c86b24284aca09da6055ef721ff7a18cd7b Mon Sep 17 00:00:00 2001 From: lemon Date: Sun, 16 Nov 2025 09:19:14 +0100 Subject: factor type stuff into type.h --- c/c.h | 1 + c/lex.h | 1 + common.h | 209 +-------------------------------------------------------------- ir/ir.h | 14 +++++ targ.c | 1 + type.c | 2 +- type.h | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 219 insertions(+), 209 deletions(-) create mode 100644 type.h diff --git a/c/c.h b/c/c.h index e8e797c..f0d42a1 100644 --- a/c/c.h +++ b/c/c.h @@ -1,4 +1,5 @@ #include "../common.h" +#include "../type.h" /*************/ /* EXPR TREE */ diff --git a/c/lex.h b/c/lex.h index daed23c..fd84f0a 100644 --- a/c/lex.h +++ b/c/lex.h @@ -1,4 +1,5 @@ #include "../common.h" +#include "../type.h" static inline bool joinspan(struct span0 *dst, struct span0 snd) diff --git a/common.h b/common.h index c2f95d6..ae7d61f 100644 --- a/common.h +++ b/common.h @@ -143,202 +143,10 @@ extern struct inclpaths { const char *path; } *cinclpaths; -/*************************/ -/** TYPE REPRESENTATION **/ -/*************************/ - -enum qualifier { - QCONST = 1<<0, - QVOLATILE = 1<<1, - QNORETURN = 1<<2, /* functions */ - QINLINE = 1<<3, /* functions */ -}; - -enum typetag { /* ordering is important here! */ - TYXXX, - TYENUM, - TYBOOL, TYCHAR, TYSCHAR, TYUCHAR, TYSHORT, TYUSHORT, TYINT, TYUINT, TYLONG, TYULONG, TYVLONG, TYUVLONG, - TYFLOAT, TYDOUBLE, TYLDOUBLE, - TYVOID, - TYPTR, TYARRAY, TYFUNC, - TYSTRUCT, TYUNION, - NTYPETAG, - TYSIGNEDSET_ = 1<> (t) & 1) -#define isunsignedt(t) ((TYUNSIGNEDSET_ | !targ_charsigned << TYCHAR) >> (t) & 1) -#define isfltt(t) in_range((t), TYFLOAT, TYLDOUBLE) -#define isaritht(t) in_range((t), TYENUM, TYLDOUBLE) -#define isscalart(t) (TYSCALARSET_ >> (t) & 1) -#define isptrcvtt(t) in_range((t), TYPTR, TYFUNC) -#define isaggt(t) in_range((t), TYSTRUCT, TYUNION) -#define isprim(ty) isprimt((ty).t) -#define isint(ty) isintt((ty).t) -#define issigned(ty) issignedt(scalartypet(ty)) -#define isunsigned(ty) isunsignedt(scalartypet(ty)) -#define isflt(ty) isfltt((ty).t) -#define isarith(ty) isaritht((ty).t) -#define isscalar(ty) isscalart((ty).t) -#define isptrcvt(ty) isptrcvtt((ty).t) -#define isagg(ty) isaggt((ty).t) -#define mktype(...) ((union type) {{ __VA_ARGS__ }}) - -struct enumvar { - const char *name; - union { vlong i; uvlong u; }; -}; - -struct fielddata { - union type t; - ushort off; - uchar bitsiz, - bitoff : 6, - qual : 2; -}; -struct namedfield { - const char *name; - struct fielddata f; -}; - -struct typedata { - uchar t; - ushort id; - union { - union type child; - struct { /* functions */ - const uchar *quals; /* packed N x 2bit array (NULL if no param has quals) */ - const union type *param; - }; - struct { /* aggregates */ - /* struct fieldmap { - union { - struct field *fs; - int *is; - }; - const char **k; - uint ; - } *fmap; */ - struct namedfield *fld; - }; - struct { /* enum */ - uchar backing; - struct enumvar *var; - }; - }; - union { - uint arrlen; /* array */ - struct { - short nmemb; /* functions, aggregates, enums */ - uchar align; - union { - struct { /* function */ - bool kandr : 1, variadic : 1; - }; - struct { /* aggregate */ - bool anyconst : 1, flexi : 1; - }; - }; - }; - }; - union { - uint siz; /* aggregate & array */ - union type ret; /* function */ - }; -}; - -extern struct typedata typedata[]; -extern const char *ttypenames[/*id*/]; - -#define tdqualsiz(nmemb) ((nmemb)/4 + ((nmemb)%4 != 0)) -static inline int -tdgetqual(const uchar *pqual, uint idx) -{ - return pqual ? pqual[idx/4] >> 2*(idx%4) & 3 : 0; -} -static inline void -tdsetqual(uchar *pqual, uint idx, int qual) -{ - assert(pqual); - pqual[idx/4] &= ~(3 << (2*(idx%4))); - pqual[idx/4] |= (qual&3) << (2*(idx%4)); -} - -bool isincomplete(union type); -uint typesize(union type); -uint typealign(union type); -union type mkptrtype(union type, int qual); -union type mkarrtype(union type t, int qual, uint n); -union type mkfntype(union type ret, uint n, const union type *, const uchar *qual, bool kandr, bool variadic); -union type mktagtype(const char *name, struct typedata *td); -bool getfield(struct fielddata *res, union type, const char *); -union type completetype(const char *name, int id, struct typedata *td); -union type typedecay(union type); -bool assigncompat(union type dst, union type src); -enum typetag intpromote(enum typetag); -union type cvtarith(union type a, union type b); -static inline union type -typechild(union type t) -{ - if (t.t == TYENUM) return mktype(t.backing); - if (t.flag & TFCHLDPRIM) return mktype(t.child); - if (t.flag & TFCHLDISDAT) { - union type chld = mktype(typedata[t.dat].t, .dat = t.dat); - if (chld.t == TYENUM) chld.backing = typedata[t.dat].backing; - return chld; - } - return typedata[t.dat].child; -} -static inline enum typetag -scalartypet(union type t) -{ - if (t.t == TYENUM) return t.backing; - if (isptrcvt(t)) return TYPTR; - return t.t; -} -static inline uint -typearrlen(union type t) -{ - return (t.flag & TFCHLDPRIM) ? t.arrlen : typedata[t.dat].arrlen; -} - /**********/ -/* TARGET */ +/* Target */ /**********/ -extern uint targ_valistsize; -extern uchar targ_primsizes[]; -extern uchar targ_primalign[]; -extern enum typetag targ_sizetype, targ_ptrdifftype, targ_wchartype; -extern bool targ_charsigned, targ_bigendian, targ_64bit; extern const struct mctarg *mctarg; void targ_init(const char *); @@ -468,7 +276,6 @@ struct bitset { uvlong u; }; enum { BSNBIT = 8 * sizeof(uvlong) }; #define BSSIZE(nbit) ((nbit) / BSNBIT + ((nbit) % BSNBIT != 0)) - static inline bool bstest(const struct bitset *bs, uint i) { @@ -522,20 +329,6 @@ bsiter(uint *i, struct bitset bs[/*siz*/], uint siz) } #define bs_each(T, var, bs, siz) for (T (var) = 0; bsiter(&(var), (bs), (siz)); ++(var)) -/** register set **/ -typedef uvlong regset; -#define rsset(pS, r) (*(pS) |= 1ull << (r)) -#define rsclr(pS, r) (*(pS) &=~ (1ull << (r))) -#define rstest(S, r) ((S) >> (r) & 1) -static inline bool -rsiter(int *i, uvlong rs) -{ - uvlong mask = -(1ull << *i); - if ((rs & mask) == 0) return 0; - *i = lowestsetbit(rs & mask); - return 1; -} - /********/ /** IO **/ /********/ diff --git a/ir/ir.h b/ir/ir.h index f453c51..613ef2a 100644 --- a/ir/ir.h +++ b/ir/ir.h @@ -1,4 +1,5 @@ #include "../common.h" +#include "../type.h" enum irclass { KXXX, @@ -137,6 +138,19 @@ enum { USERJUMP = 0xFFFF }; struct use { struct block *blk; ushort u; }; enum { MAXREGS = 64 }; +/** register set **/ +typedef uvlong regset; +#define rsset(pS, r) (*(pS) |= 1ull << (r)) +#define rsclr(pS, r) (*(pS) &=~ (1ull << (r))) +#define rstest(S, r) ((S) >> (r) & 1) +static inline bool +rsiter(int *i, uvlong rs) +{ + uvlong mask = -(1ull << *i); + if ((rs & mask) == 0) return 0; + *i = lowestsetbit(rs & mask); + return 1; +} struct function { struct arena **arena; diff --git a/targ.c b/targ.c index b394a9a..019f784 100644 --- a/targ.c +++ b/targ.c @@ -1,4 +1,5 @@ #include "common.h" +#include "type.h" extern const struct mctarg t_amd64_sysv; static const struct targ { diff --git a/type.c b/type.c index 8154e52..78a6278 100644 --- a/type.c +++ b/type.c @@ -1,4 +1,4 @@ -#include "common.h" +#include "type.h" struct typedata typedata[1<<13]; const char *ttypenames[1<<10]; diff --git a/type.h b/type.h new file mode 100644 index 0000000..f83a60c --- /dev/null +++ b/type.h @@ -0,0 +1,200 @@ +#ifndef TYPE_H_ +#define TYPE_H_ +#include "common.h" + +enum qualifier { + QCONST = 1<<0, + QVOLATILE = 1<<1, + QNORETURN = 1<<2, /* functions */ + QINLINE = 1<<3, /* functions */ +}; + +enum typetag { /* ordering is important here! */ + TYXXX, + TYENUM, + TYBOOL, TYCHAR, TYSCHAR, TYUCHAR, TYSHORT, TYUSHORT, TYINT, TYUINT, TYLONG, TYULONG, TYVLONG, TYUVLONG, + TYFLOAT, TYDOUBLE, TYLDOUBLE, + TYVOID, + TYPTR, TYARRAY, TYFUNC, + TYSTRUCT, TYUNION, + NTYPETAG, + TYSIGNEDSET_ = 1<> (t) & 1) +#define isunsignedt(t) ((TYUNSIGNEDSET_ | !targ_charsigned << TYCHAR) >> (t) & 1) +#define isfltt(t) in_range((t), TYFLOAT, TYLDOUBLE) +#define isaritht(t) in_range((t), TYENUM, TYLDOUBLE) +#define isscalart(t) (TYSCALARSET_ >> (t) & 1) +#define isptrcvtt(t) in_range((t), TYPTR, TYFUNC) +#define isaggt(t) in_range((t), TYSTRUCT, TYUNION) +#define isprim(ty) isprimt((ty).t) +#define isint(ty) isintt((ty).t) +#define issigned(ty) issignedt(scalartypet(ty)) +#define isunsigned(ty) isunsignedt(scalartypet(ty)) +#define isflt(ty) isfltt((ty).t) +#define isarith(ty) isaritht((ty).t) +#define isscalar(ty) isscalart((ty).t) +#define isptrcvt(ty) isptrcvtt((ty).t) +#define isagg(ty) isaggt((ty).t) +#define mktype(...) ((union type) {{ __VA_ARGS__ }}) + +struct enumvar { + const char *name; + union { vlong i; uvlong u; }; +}; + +struct fielddata { + union type t; + ushort off; + uchar bitsiz, + bitoff : 6, + qual : 2; +}; +struct namedfield { + const char *name; + struct fielddata f; +}; + +struct typedata { + uchar t; + ushort id; + union { + union type child; + struct { /* functions */ + const uchar *quals; /* packed N x 2bit array (NULL if no param has quals) */ + const union type *param; + }; + struct { /* aggregates */ + /* struct fieldmap { + union { + struct field *fs; + int *is; + }; + const char **k; + uint ; + } *fmap; */ + struct namedfield *fld; + }; + struct { /* enum */ + uchar backing; + struct enumvar *var; + }; + }; + union { + uint arrlen; /* array */ + struct { + short nmemb; /* functions, aggregates, enums */ + uchar align; + union { + struct { /* function */ + bool kandr : 1, variadic : 1; + }; + struct { /* aggregate */ + bool anyconst : 1, flexi : 1; + }; + }; + }; + }; + union { + uint siz; /* aggregate & array */ + union type ret; /* function */ + }; +}; + +extern struct typedata typedata[]; +extern const char *ttypenames[/*id*/]; + +#define tdqualsiz(nmemb) ((nmemb)/4 + ((nmemb)%4 != 0)) +static inline int +tdgetqual(const uchar *pqual, uint idx) +{ + return pqual ? pqual[idx/4] >> 2*(idx%4) & 3 : 0; +} +static inline void +tdsetqual(uchar *pqual, uint idx, int qual) +{ + assert(pqual); + pqual[idx/4] &= ~(3 << (2*(idx%4))); + pqual[idx/4] |= (qual&3) << (2*(idx%4)); +} + +bool isincomplete(union type); +uint typesize(union type); +uint typealign(union type); +union type mkptrtype(union type, int qual); +union type mkarrtype(union type t, int qual, uint n); +union type mkfntype(union type ret, uint n, const union type *, const uchar *qual, bool kandr, bool variadic); +union type mktagtype(const char *name, struct typedata *td); +bool getfield(struct fielddata *res, union type, const char *); +union type completetype(const char *name, int id, struct typedata *td); +union type typedecay(union type); +bool assigncompat(union type dst, union type src); +enum typetag intpromote(enum typetag); +union type cvtarith(union type a, union type b); +static inline union type +typechild(union type t) +{ + if (t.t == TYENUM) return mktype(t.backing); + if (t.flag & TFCHLDPRIM) return mktype(t.child); + if (t.flag & TFCHLDISDAT) { + union type chld = mktype(typedata[t.dat].t, .dat = t.dat); + if (chld.t == TYENUM) chld.backing = typedata[t.dat].backing; + return chld; + } + return typedata[t.dat].child; +} +static inline enum typetag +scalartypet(union type t) +{ + if (t.t == TYENUM) return t.backing; + if (isptrcvt(t)) return TYPTR; + return t.t; +} +static inline uint +typearrlen(union type t) +{ + return (t.flag & TFCHLDPRIM) ? t.arrlen : typedata[t.dat].arrlen; +} + +/**********/ +/* Target */ +/**********/ + +extern uint targ_valistsize; +extern uchar targ_primsizes[]; +extern uchar targ_primalign[]; +extern enum typetag targ_sizetype, targ_ptrdifftype, targ_wchartype; +extern bool targ_charsigned, targ_bigendian, targ_64bit; + +#endif + +/* vim:set ts=3 sw=3 expandtab: */ -- cgit v1.2.3