diff options
| author | 2026-03-02 17:52:57 +0100 | |
|---|---|---|
| committer | 2026-03-02 17:52:57 +0100 | |
| commit | f2285400e65dafe730a073b3ca92494d72c7295b (patch) | |
| tree | d5a96f09fbd0402ada3c39165a9d2d8202ee8e5d /c/builtin.c | |
| parent | a498f851ef2f50c9b8ac47e238137af52b54057d (diff) | |
add bswap16/32/64
- frontend: __builtin_bswapX intrinsics
- backend: ObswapX instructions
Diffstat (limited to 'c/builtin.c')
| -rw-r--r-- | c/builtin.c | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/c/builtin.c b/c/builtin.c index aabd750..5c59857 100644 --- a/c/builtin.c +++ b/c/builtin.c @@ -32,13 +32,13 @@ callcheck(const struct span *span, int nparam, const union type *param, int narg return callcheck(&ex->span, countof(par)-1, par+1, ex->narg, ex->sub+1); \ } +/* __builtin_va_start */ static bool va_start_sema(struct comp *cm, struct expr *ex) { ex->ty = mktype(TYVOID); return callcheck(&ex->span, 1, &cvalistty, ex->narg, ex->sub+1); } - static union ref va_start_comp(struct function *fn, struct expr *ex, bool discard) { @@ -50,8 +50,7 @@ va_start_comp(struct function *fn, struct expr *ex, bool discard) return NOREF; } -DEF_FNLIKE_SEMA(trap, mktype(TYVOID), ) - +/* __builtin_va_end */ static bool va_end_sema(struct comp *cm, struct expr *ex) { @@ -65,13 +64,13 @@ va_end_comp(struct function *fn, struct expr *ex, bool discard) return NOREF; } +/* __builtin_va_copy */ DEF_FNLIKE_SEMA(va_copy, mktype(TYVOID), cvalistty, cvalistty) - static union ref va_copy_comp(struct function *fn, struct expr *ex, bool discard) { union irtype typ = mkirtype(cvalistty.t == TYARRAY ? typechild(cvalistty) : cvalistty); - for (int i = 1; i < 2; ++i) + for (int i = 1; i <= 2; ++i) assert(typedecay(ex->sub[i].ty).bits == typedecay(cvalistty).bits); union ref dst = compileexpr(fn, &ex->sub[1], 0), src = compileexpr(fn, &ex->sub[2], 0); addinstr(fn, mkarginstr(typ, dst)); @@ -80,6 +79,8 @@ va_copy_comp(struct function *fn, struct expr *ex, bool discard) return NOREF; } +/* __builtin_trap */ +DEF_FNLIKE_SEMA(trap, mktype(TYVOID), ) static union ref trap_comp(struct function *fn, struct expr *ex, bool discard) { @@ -88,17 +89,51 @@ trap_comp(struct function *fn, struct expr *ex, bool discard) return NOREF; } -union ref -builtin_va_arg_comp(struct function *fn, const struct expr *ex, bool discard) +static inline union ref +cvtintref(struct function *fn, enum irclass dst, union ref src) { - assert(ex->t == EVAARG && ex->ty.t); - enum irclass k = isagg(ex->ty) ? KPTR : type2cls[scalartypet(ex->ty)]; - return addinstr(fn, mkinstr(Ovaarg, k, compileexpr(fn, ex->sub, 0), mktyperef(mkirtype(ex->ty)))); + if (src.t == RTMP) { + if (insrescls(instrtab[src.i]) != dst) + return addinstr(fn, mkinstr(Ocopy, dst, src)); + return src; + } else if (isintcon(src)) { + vlong x = intconval(src); + return mkintcon(dst, cls2siz[dst] == 4 ? (int)x : x); + } + assert(!"int ref?"); +} + +/* __builtin_bswap16 */ +DEF_FNLIKE_SEMA(bswap16, mktype(TYUSHORT), mktype(TYUSHORT)) +static union ref +bswap16_comp(struct function *fn, struct expr *ex, bool discard) +{ + assert(isint(ex->ty)); + return irunop(fn, Obswap16, KI32, scalarcvt(fn, ex->ty, ex->sub[1].ty, + compileexpr(fn, &ex->sub[1], 0))); +} +/* __builtin_bswap32 */ +DEF_FNLIKE_SEMA(bswap32, mktype(TYUINT), mktype(TYUINT)) +static union ref +bswap32_comp(struct function *fn, struct expr *ex, bool discard) +{ + assert(isint(ex->ty)); + return irunop(fn, Obswap32, KI32, scalarcvt(fn, ex->ty, ex->sub[1].ty, + compileexpr(fn, &ex->sub[1], 0))); +} +/* __builtin_bswap64 */ +DEF_FNLIKE_SEMA(bswap64, mktype(TYUVLONG), mktype(TYUVLONG)) +static union ref +bswap64_comp(struct function *fn, struct expr *ex, bool discard) +{ + assert(isint(ex->ty)); + return irunop(fn, Obswap64, KI64, scalarcvt(fn, ex->ty, ex->sub[1].ty, + compileexpr(fn, &ex->sub[1], 0))); } #define LIST_BUILTINS(_) \ _(va_start) _(va_copy) _(va_end) \ - _(trap) + _(trap) _(bswap16) _(bswap32) _(bswap64) static const struct { const char *name; @@ -121,6 +156,15 @@ putbuiltins(struct env *env) } } +/* this is separate because it's a keyword */ +union ref +builtin_va_arg_comp(struct function *fn, const struct expr *ex, bool discard) +{ + assert(ex->t == EVAARG && ex->ty.t); + enum irclass k = isagg(ex->ty) ? KPTR : type2cls[scalartypet(ex->ty)]; + return addinstr(fn, mkinstr(Ovaarg, k, compileexpr(fn, ex->sub, 0), mktyperef(mkirtype(ex->ty)))); +} + bool hasbuiltin(const char *name, uint len) { |