commit f1e91a7c2257e38b8244f99c4066cabea0336507
parent 50f2be4ee7f358e1fa5abd6b3808d6a4c4742cd6
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 1 Jun 2026 13:04:25 -0700
frontend: replace the cg_public_compat.h macro shim with direct pcg_* calls
The C parser drove codegen through a family of cg_*(g, ...) forwarding
macros in cg_public_compat.h -- a compatibility shim that mimicked an
older, richer CG-handle API on top of today's leaner cfree_cg_*. Every
macro ignored its `g` argument (always p->cg) and forwarded to the real
pcg_* adapter, so the layer bought nothing but indirection and a
misleading "compat" name.
- Promote the 13 macros that expanded inline (emit guard + type-stack
mirroring) to real pcg_* functions in cg_adapter.c: set_loc, func_end,
dup, swap, drop, va_start/end/copy, label_new/place, jump,
branch_true/false.
- Rewrite all ~530 call sites: cg_X(p->cg, ...) -> pcg_X(p, ...).
- Rename cg_public_compat.h -> cg_adapter.h to match its companion
cg_adapter.c; delete the 44 forwarding macros and the unused CGScope
typedef.
- Drop a vestigial cg_public_compat.h include from decl.c (it only used
<cfree/cg.h> symbols).
- Update doc/FRONTENDS.md and doc/INTERFACES.md to the new name.
No behavior change: each promoted function is byte-for-byte equivalent to
the macro it replaced. test-parse 3784/0/0, test-toy 1338/0/24,
smoke-x64 green; debug (-Werror + ASan/UBSan) and release builds clean.
Diffstat:
12 files changed, 926 insertions(+), 932 deletions(-)
diff --git a/doc/FRONTENDS.md b/doc/FRONTENDS.md
@@ -195,16 +195,15 @@ side holds the static types and lvalue bookkeeping needed to drive the next op
correctly (signedness for division/compare/shift, pointer-element size for
arithmetic, bit-field metadata for loads/stores, and so on).
-### The cg_public_compat.h coupling point
+### The cg_adapter.h coupling point
-`lang/c/parse/cg_adapter.c` and its header `cg_public_compat.h` are the real
+`lang/c/parse/cg_adapter.c` and its header `cg_adapter.h` are the real
parser <-> codegen seam, and the most load-bearing design decision in the C
-frontend. The header defines a family of `pcg_*` helpers and a set of
-`cg_*` macros that look like thin wrappers over the public `cfree_cg_*` API but
-do two extra jobs on every call:
+frontend. The header declares a family of `pcg_*` helpers that look like thin
+wrappers over the public `cfree_cg_*` API but do two extra jobs on every call:
- **They keep the parser's typed value stack in lockstep with the CG stack.**
- `cg_dup`/`cg_swap`/`cg_drop` mirror the structural op onto the type stack;
+ `pcg_dup`/`pcg_swap`/`pcg_drop` mirror the structural op onto the type stack;
`pcg_push_int` / `pcg_load` / `pcg_binop` / `pcg_convert` push, retag, or pop
type-stack entries alongside emitting the CG op. The parser never calls
`cfree_cg_*` for stack-affecting ops directly — it goes through `pcg_*` so
@@ -221,9 +220,7 @@ do two extra jobs on every call:
a pointer.
The implication: **the C frontend's lowering strategy is encoded in this
-shim, not in the public CG contract.** The compatibility-header name reflects
-its history — it preserves the call shapes of an older richer CG surface on
-top of today's leaner one — but in practice it is where C-specific decisions
+adapter, not in the public CG contract.** It is where C-specific decisions
(lvalue-as-effective-address, lazy load/store/addr, the typed shadow stack)
are concentrated. A change to how C lowers indirection lands here, not in the
backends. (`pcg_emit_enabled` also lets the parser run constant-folding /
diff --git a/doc/INTERFACES.md b/doc/INTERFACES.md
@@ -297,7 +297,7 @@ them — plus the two documented internal exceptions noted in the boundary map.
| wasm (`lang/wasm/`) | `cfree_wasm_frontend_vtable` (`wasm.h`) | reaches `wasm/wasm.h` (shared module model) |
**Frontend-tier notes:**
-- `lang/c/parse/cg_public_compat.h` is a compatibility shim that wraps `cg.h`
+- `lang/c/parse/cg_adapter.h` is the C parser's codegen adapter: it wraps `cg.h`
with C-semantic sugar (lvalue auxiliaries, the type stack, `pcg_*` helpers). It
is the real coupling point between the C parser and codegen, and it is worth
understanding when working in either: it carries the C frontend's own policy on
diff --git a/lang/c/decl/decl.c b/lang/c/decl/decl.c
@@ -18,8 +18,6 @@
#include <string.h>
-#include "parse/cg_public_compat.h"
-
struct DeclTable {
Compiler* c;
Pool* pool;
diff --git a/lang/c/parse/cg_adapter.c b/lang/c/parse/cg_adapter.c
@@ -141,6 +141,24 @@ void pcg_rot3_type(Parser* p) {
}
}
+/* Structural CG ops that must keep the parser's typed shadow stack in lockstep
+ * with the CG stack: each emits the CG op (when codegen is enabled) and mirrors
+ * the same structural effect onto the type stack. */
+void pcg_dup(Parser* p) {
+ if (pcg_emit_enabled(p)) cfree_cg_dup(p->cg);
+ pcg_dup_type(p);
+}
+
+void pcg_swap(Parser* p) {
+ if (pcg_emit_enabled(p)) cfree_cg_swap(p->cg);
+ pcg_swap_type(p);
+}
+
+void pcg_drop(Parser* p) {
+ if (pcg_emit_enabled(p)) cfree_cg_drop(p->cg);
+ pcg_drop_type(p);
+}
+
PcgLvAux* pcg_top_lv_aux(Parser* p) {
return p->cg_type_sp ? &p->cg_lv_aux[p->cg_type_sp - 1u] : NULL;
}
@@ -396,6 +414,14 @@ void pcg_func_begin(Parser* p, const CGFuncDesc* fd) {
}
}
+void pcg_func_end(Parser* p) {
+ if (pcg_emit_enabled(p)) cfree_cg_func_end(p->cg);
+}
+
+void pcg_set_loc(Parser* p, SrcLoc loc) {
+ if (pcg_emit_enabled(p)) cfree_cg_set_loc(p->cg, loc);
+}
+
void pcg_push_int(Parser* p, i64 v, const Type* ty) {
if (pcg_emit_enabled(p)) {
cfree_cg_push_int(p->cg, (uint64_t)v, pcg_tid(p, ty));
@@ -554,6 +580,32 @@ void pcg_computed_goto(Parser* p, const CGLabel* targets, u32 ntargets) {
pcg_drop_type(p);
}
+/* ---- Control flow ----
+ *
+ * Labels are pure bookkeeping handles, so pcg_label_new always mints one (it
+ * has no codegen side effect to suppress). The placement / jump / branch ops
+ * gate on emit; the conditional branches also pop the tested value off the
+ * type stack to mirror the CG-side consume. */
+CGLabel pcg_label_new(Parser* p) { return cfree_cg_label_new(p->cg); }
+
+void pcg_label_place(Parser* p, CGLabel l) {
+ if (pcg_emit_enabled(p)) cfree_cg_label_place(p->cg, l);
+}
+
+void pcg_jump(Parser* p, CGLabel l) {
+ if (pcg_emit_enabled(p)) cfree_cg_jump(p->cg, l);
+}
+
+void pcg_branch_true(Parser* p, CGLabel l) {
+ if (pcg_emit_enabled(p)) cfree_cg_branch_true(p->cg, l);
+ pcg_drop_type(p);
+}
+
+void pcg_branch_false(Parser* p, CGLabel l) {
+ if (pcg_emit_enabled(p)) cfree_cg_branch_false(p->cg, l);
+ pcg_drop_type(p);
+}
+
/* Store [lv, rv] -> [rv]. The expression-value of an assignment is the
* assigned rvalue, so the store sequence must leave a copy of rv on TOS. */
void pcg_store(Parser* p) {
@@ -1004,6 +1056,18 @@ void pcg_va_arg(Parser* p, const Type* ty) {
pcg_push_type(p, ty);
}
+void pcg_va_start(Parser* p) {
+ if (pcg_emit_enabled(p)) cfree_cg_vararg_start(p->cg);
+}
+
+void pcg_va_end(Parser* p) {
+ if (pcg_emit_enabled(p)) cfree_cg_vararg_end(p->cg);
+}
+
+void pcg_va_copy(Parser* p) {
+ if (pcg_emit_enabled(p)) cfree_cg_vararg_copy(p->cg);
+}
+
void pcg_atomic_load(Parser* p, MemOrder ord) {
const Type* pty = pcg_top_type(p);
const Type* ty = (pty && pty->kind == TY_PTR) ? pty->ptr.pointee : pty;
diff --git a/lang/c/parse/cg_adapter.h b/lang/c/parse/cg_adapter.h
@@ -0,0 +1,334 @@
+#ifndef CFREE_PARSE_CG_ADAPTER_H
+#define CFREE_PARSE_CG_ADAPTER_H
+
+/* cg_adapter.h — the C parser <-> codegen seam.
+ *
+ * Declares the `pcg_*` helpers (implemented in cg_adapter.c) plus the
+ * C-frontend types they operate on. Every `pcg_*` call keeps the parser's
+ * typed shadow stack (cg_type_stack / cg_value_flags / cg_lv_aux in struct
+ * Parser) in lockstep with the public CG stack and folds C lvalue chains into
+ * single effective-address memops; the parser never calls stack-affecting
+ * `cfree_cg_*` ops directly. See doc/FRONTENDS.md for the design. */
+
+#include <cfree/cg.h>
+
+#include "c_support.h"
+#include "type/type.h"
+
+typedef CfreeCg CG;
+typedef CfreeCgLabel CGLabel;
+typedef CfreeCgLocal FrameSlot;
+
+#define FRAME_SLOT_NONE CFREE_CG_LOCAL_NONE
+#define OBJ_GROUP_NONE 0u
+
+/* Lvalue auxiliary state, carried parallel to cg_type_stack / cg_value_flags.
+ *
+ * The C parser tracks one logical "C-language value" per stack slot. When that
+ * slot is a C-language lvalue (PCG_VALUE_LVALUE), the aux below records the
+ * pending effective-address modifiers and bit-field metadata that the next
+ * load / store / addr will fold onto the CG memop.
+ *
+ * Lvalue chains (`s.f`, `a[i].g`, etc.) accumulate into this aux instead of
+ * emitting per-step CG ops: there is no CG-level `field` / `index` /
+ * `addr_offset` op anymore. Field offsets bump `offset`; subscripts set
+ * `scale` and leave the evaluated index value on the CG stack just above the
+ * lvalue base. Bit-field selections fill `bit_*`. The aux is consumed by the
+ * very next pcg_load / pcg_store / pcg_addr that crosses the slot.
+ *
+ * `base_kind` records what the CG-stack base under this lvalue actually is —
+ * either an OPK_LOCAL produced by push_local (PCG_LV_BASE_LOCAL) or a
+ * pointer rvalue from push_symbol_addr, push_local_addr, dereference, or
+ * pointer arithmetic (PCG_LV_BASE_POINTER_RV). Stream A's CG-side memops
+ * accept either shape uniformly; pcg_addr uses the distinction to decide
+ * whether to emit cfree_cg_addr or treat the base as already-a-pointer. */
+typedef enum PcgLvBaseKind {
+ PCG_LV_BASE_LOCAL = 0,
+ PCG_LV_BASE_POINTER_RV = 1,
+} PcgLvBaseKind;
+
+typedef struct PcgLvAux {
+ i64 offset;
+ u32 scale;
+ u16 bit_offset;
+ u16 bit_width;
+ u32 storage_size;
+ u8 bit_signed;
+ u8 base_kind; /* PcgLvBaseKind */
+ u8 is_subobject; /* lvalue is a member/element of a larger CG object */
+ u8 pad[5];
+} PcgLvAux;
+
+typedef enum BinOp {
+ BO_IADD,
+ BO_ISUB,
+ BO_IMUL,
+ BO_SDIV,
+ BO_UDIV,
+ BO_SREM,
+ BO_UREM,
+ BO_FADD,
+ BO_FSUB,
+ BO_FMUL,
+ BO_FDIV,
+ BO_AND,
+ BO_OR,
+ BO_XOR,
+ BO_SHL,
+ BO_SHR_S,
+ BO_SHR_U,
+} BinOp;
+
+typedef enum UnOp {
+ UO_NEG,
+ UO_NOT,
+ UO_BNOT,
+} UnOp;
+
+typedef enum CmpOp {
+ CMP_EQ,
+ CMP_NE,
+ CMP_LT_S,
+ CMP_LE_S,
+ CMP_GT_S,
+ CMP_GE_S,
+ CMP_LT_U,
+ CMP_LE_U,
+ CMP_GT_U,
+ CMP_GE_U,
+ CMP_LT_F,
+ CMP_LE_F,
+ CMP_GT_F,
+ CMP_GE_F,
+} CmpOp;
+
+typedef enum AtomicOp {
+ AO_XCHG,
+ AO_ADD,
+ AO_SUB,
+ AO_AND,
+ AO_OR,
+ AO_XOR,
+ AO_NAND,
+} AtomicOp;
+
+typedef enum MemOrder {
+ MO_RELAXED,
+ MO_CONSUME,
+ MO_ACQUIRE,
+ MO_RELEASE,
+ MO_ACQ_REL,
+ MO_SEQ_CST,
+} MemOrder;
+
+typedef enum IntrinKind {
+ INTRIN_NONE = 0,
+ INTRIN_POPCOUNT,
+ INTRIN_CTZ,
+ INTRIN_CLZ,
+ INTRIN_BSWAP16,
+ INTRIN_BSWAP32,
+ INTRIN_BSWAP64,
+ INTRIN_MEMCPY,
+ INTRIN_MEMMOVE,
+ INTRIN_MEMSET,
+ INTRIN_PREFETCH,
+ INTRIN_ASSUME_ALIGNED,
+ INTRIN_EXPECT,
+ INTRIN_UNREACHABLE,
+ INTRIN_TRAP,
+ INTRIN_SETJMP,
+ INTRIN_LONGJMP,
+ INTRIN_SADD_OVERFLOW,
+ INTRIN_UADD_OVERFLOW,
+ INTRIN_SSUB_OVERFLOW,
+ INTRIN_USUB_OVERFLOW,
+ INTRIN_SMUL_OVERFLOW,
+ INTRIN_UMUL_OVERFLOW,
+} IntrinKind;
+
+typedef enum AsmDir { ASM_IN, ASM_OUT, ASM_INOUT } AsmDir;
+
+typedef struct AsmConstraint {
+ const char* str;
+ Sym name;
+ const Type* type;
+ u8 dir;
+ u8 pad[3];
+} AsmConstraint;
+
+typedef enum FrameSlotKind {
+ FS_LOCAL,
+ FS_PARAM,
+ FS_SPILL,
+ FS_SRET,
+ FS_ALLOCA,
+} FrameSlotKind;
+
+typedef enum FrameSlotFlag {
+ FSF_NONE = 0,
+ FSF_ADDR_TAKEN = 1u << 0,
+ FSF_VOLATILE = 1u << 1,
+} FrameSlotFlag;
+
+typedef struct FrameSlotDesc {
+ const Type* type;
+ Sym name;
+ SrcLoc loc;
+ u32 size;
+ u32 align;
+ u8 kind;
+ u8 pad;
+ u16 flags;
+} FrameSlotDesc;
+
+typedef struct CGParamDesc {
+ u32 index;
+ Sym name;
+ const Type* type;
+ FrameSlot slot;
+ const void* abi;
+ const void* incoming;
+ u32 nincoming;
+ SrcLoc loc;
+} CGParamDesc;
+
+typedef enum CGFuncDescFlag {
+ CGFD_NONE = 0,
+ CGFD_NORETURN = 1u << 0,
+} CGFuncDescFlag;
+
+typedef struct CGFuncDesc {
+ ObjSymId sym;
+ ObjSecId text_section_id;
+ u32 group_id;
+ const Type* fn_type;
+ const void* abi;
+ const CGParamDesc* params;
+ u32 nparams;
+ SrcLoc loc;
+ u32 flags;
+ CfreeCgInlinePolicy inline_policy;
+} CGFuncDesc;
+
+typedef struct Parser Parser;
+
+CfreeCgTypeId pcg_tid(Parser*, const Type*);
+CfreeCgMemAccess pcg_mem(Parser*, const Type*);
+const Type* pcg_top_type(Parser*);
+const Type* pcg_top2_type(Parser*);
+void pcg_retag_top(Parser*, const Type*);
+void pcg_push_type(Parser*, const Type*);
+void pcg_drop_type(Parser*);
+void pcg_dup_type(Parser*);
+void pcg_swap_type(Parser*);
+/* Structural CG ops that also mirror onto the typed shadow stack. */
+void pcg_dup(Parser*);
+void pcg_swap(Parser*);
+void pcg_drop(Parser*);
+int pcg_top_is_bitfield(Parser*);
+void pcg_set_top_bitfield(Parser*);
+int pcg_top_is_register(Parser*);
+void pcg_set_top_register(Parser*);
+int pcg_top_is_lvalue(Parser*);
+int pcg_top_is_modifiable_lvalue(Parser*);
+int pcg_top_is_null_ptr_const(Parser*);
+void pcg_set_top_lvalue(Parser*);
+void pcg_rot3_type(Parser*);
+int pcg_emit_enabled(Parser*);
+void pcg_codegen_suppress_push(Parser*);
+void pcg_codegen_suppress_pop(Parser*);
+
+CfreeCgIntBinOp pcg_int_binop(BinOp);
+CfreeCgFpBinOp pcg_fp_binop(BinOp);
+CfreeCgIntCmpOp pcg_int_cmp(CmpOp);
+CfreeCgFpCmpOp pcg_fp_cmp(CmpOp);
+CfreeCgAtomicOp pcg_atomic_op(AtomicOp);
+CfreeCgMemOrder pcg_mem_order(MemOrder);
+int pcg_type_is_fp(const Type*);
+int pcg_type_is_signed(const Type*);
+
+FrameSlot pcg_local(Parser*, const FrameSlotDesc*);
+FrameSlot pcg_param_slot(Parser*, u32, const FrameSlotDesc*);
+void pcg_param(Parser*, const CGParamDesc*);
+void pcg_func_begin(Parser*, const CGFuncDesc*);
+void pcg_func_end(Parser*);
+void pcg_set_loc(Parser*, SrcLoc);
+void pcg_push_int(Parser*, i64, const Type*);
+void pcg_push_float(Parser*, double, const Type*);
+void pcg_push_local_typed(Parser*, FrameSlot, const Type*);
+void pcg_push_global(Parser*, ObjSymId, const Type*);
+void pcg_load(Parser*);
+void pcg_addr(Parser*);
+void pcg_push_label_addr(Parser*, CGLabel);
+void pcg_computed_goto(Parser*, const CGLabel*, u32);
+CGLabel pcg_label_new(Parser*);
+void pcg_label_place(Parser*, CGLabel);
+void pcg_jump(Parser*, CGLabel);
+void pcg_branch_true(Parser*, CGLabel);
+void pcg_branch_false(Parser*, CGLabel);
+void pcg_store(Parser*);
+void pcg_deref(Parser*, const Type*);
+
+/* ---- Lvalue auxiliary access ----
+ *
+ * pcg_top_lv_aux returns a mutable pointer to TOS's lvalue aux, used by
+ * parse_postfix and the initializer / compound-assignment paths to fold
+ * field offsets and bit-field metadata inline. Returns NULL if the parser
+ * stack is empty; behavior on a non-lvalue TOS is the caller's responsibility
+ * (parse_postfix has already validated lvalueness before calling). */
+PcgLvAux* pcg_top_lv_aux(Parser*);
+PcgLvAux* pcg_lv_aux_at(Parser*, u32 depth);
+
+/* ---- Lvalue chain helpers ----
+ *
+ * Each maps directly to the canonical encodings in doc/INDIRECT.md without
+ * emitting any intermediate field / index / addr_offset CG op. Field offsets
+ * and array scales are accumulated on the TOS lvalue's aux; the next
+ * pcg_load / pcg_store / pcg_addr consumes them. */
+
+/* Fold `s.f` (or any path-resolved field selection) into the TOS lvalue.
+ * byte_offset is the cumulative offset within the record; ty is the field
+ * type; bf_* are bit-field metadata (bf_width == 0 for non-bitfields). The
+ * caller is responsible for verifying TOS is an lvalue of a record type. */
+void pcg_lv_member(Parser*, i64 byte_offset, const Type* field_ty,
+ u16 bf_offset, u16 bf_width, u32 bf_storage_size);
+
+/* Attach `[index]` to the TOS lvalue. PRECONDITION: the index value has just
+ * been pushed onto the CG stack (and parser stack) above the lvalue base;
+ * the parser stack therefore has [base_lv, index] at depth [1, 0]. This call
+ * records `scale = elem_size` on the base's aux, drops the index parser
+ * slot (leaving the index value on the CG stack for the eventual memop),
+ * and retags the surviving slot as elem_ty (lvalue). */
+void pcg_lv_subscript(Parser*, u32 elem_size, const Type* elem_ty);
+
+/* Decay an array lvalue at TOS into a pointer-to-element rvalue. Emits
+ * cfree_cg_addr (or a no-op for pointer-rvalue bases) and folds any pending
+ * EA modifiers into the resulting pointer via ptr arithmetic. After return,
+ * TOS is a pointer rvalue of type `*arr_ty->elem`. */
+void pcg_decay_array(Parser*, const Type* arr_ty);
+
+void pcg_binop(Parser*, BinOp);
+void pcg_unop(Parser*, UnOp);
+void pcg_cmp(Parser*, CmpOp);
+void pcg_convert(Parser*, const Type*);
+void pcg_inc_dec(Parser*, BinOp, int);
+void pcg_call(Parser*, u32, const Type*);
+void pcg_call_symbol(Parser*, CfreeCgSym, u32, const Type*);
+void pcg_ret(Parser*, int);
+void pcg_alloca(Parser*);
+void pcg_va_arg(Parser*, const Type*);
+void pcg_va_start(Parser*);
+void pcg_va_end(Parser*);
+void pcg_va_copy(Parser*);
+void pcg_atomic_load(Parser*, MemOrder);
+void pcg_atomic_store(Parser*, MemOrder);
+void pcg_atomic_rmw(Parser*, AtomicOp, MemOrder);
+void pcg_atomic_cas(Parser*, MemOrder, MemOrder);
+void pcg_fence(Parser*, MemOrder);
+void pcg_intrinsic_unary_to_int(Parser*, IntrinKind);
+void pcg_intrinsic_void(Parser*, IntrinKind);
+void pcg_inline_asm(Parser*, const char*, const AsmConstraint*, u32,
+ const AsmConstraint*, u32, const Sym*, u32);
+
+#endif
diff --git a/lang/c/parse/cg_public_compat.h b/lang/c/parse/cg_public_compat.h
@@ -1,399 +0,0 @@
-#ifndef CFREE_PARSE_CG_PUBLIC_COMPAT_H
-#define CFREE_PARSE_CG_PUBLIC_COMPAT_H
-
-#include <cfree/cg.h>
-
-#include "c_support.h"
-#include "type/type.h"
-
-typedef CfreeCg CG;
-typedef CfreeCgLabel CGLabel;
-typedef CfreeCgScope CGScope;
-typedef CfreeCgLocal FrameSlot;
-
-#define FRAME_SLOT_NONE CFREE_CG_LOCAL_NONE
-#define OBJ_GROUP_NONE 0u
-
-/* Lvalue auxiliary state, carried parallel to cg_type_stack / cg_value_flags.
- *
- * The C parser tracks one logical "C-language value" per stack slot. When that
- * slot is a C-language lvalue (PCG_VALUE_LVALUE), the aux below records the
- * pending effective-address modifiers and bit-field metadata that the next
- * load / store / addr will fold onto the CG memop.
- *
- * Lvalue chains (`s.f`, `a[i].g`, etc.) accumulate into this aux instead of
- * emitting per-step CG ops: there is no CG-level `field` / `index` /
- * `addr_offset` op anymore. Field offsets bump `offset`; subscripts set
- * `scale` and leave the evaluated index value on the CG stack just above the
- * lvalue base. Bit-field selections fill `bit_*`. The aux is consumed by the
- * very next pcg_load / pcg_store / pcg_addr that crosses the slot.
- *
- * `base_kind` records what the CG-stack base under this lvalue actually is —
- * either an OPK_LOCAL produced by push_local (PCG_LV_BASE_LOCAL) or a
- * pointer rvalue from push_symbol_addr, push_local_addr, dereference, or
- * pointer arithmetic (PCG_LV_BASE_POINTER_RV). Stream A's CG-side memops
- * accept either shape uniformly; pcg_addr uses the distinction to decide
- * whether to emit cfree_cg_addr or treat the base as already-a-pointer. */
-typedef enum PcgLvBaseKind {
- PCG_LV_BASE_LOCAL = 0,
- PCG_LV_BASE_POINTER_RV = 1,
-} PcgLvBaseKind;
-
-typedef struct PcgLvAux {
- i64 offset;
- u32 scale;
- u16 bit_offset;
- u16 bit_width;
- u32 storage_size;
- u8 bit_signed;
- u8 base_kind; /* PcgLvBaseKind */
- u8 is_subobject; /* lvalue is a member/element of a larger CG object */
- u8 pad[5];
-} PcgLvAux;
-
-typedef enum BinOp {
- BO_IADD,
- BO_ISUB,
- BO_IMUL,
- BO_SDIV,
- BO_UDIV,
- BO_SREM,
- BO_UREM,
- BO_FADD,
- BO_FSUB,
- BO_FMUL,
- BO_FDIV,
- BO_AND,
- BO_OR,
- BO_XOR,
- BO_SHL,
- BO_SHR_S,
- BO_SHR_U,
-} BinOp;
-
-typedef enum UnOp {
- UO_NEG,
- UO_NOT,
- UO_BNOT,
-} UnOp;
-
-typedef enum CmpOp {
- CMP_EQ,
- CMP_NE,
- CMP_LT_S,
- CMP_LE_S,
- CMP_GT_S,
- CMP_GE_S,
- CMP_LT_U,
- CMP_LE_U,
- CMP_GT_U,
- CMP_GE_U,
- CMP_LT_F,
- CMP_LE_F,
- CMP_GT_F,
- CMP_GE_F,
-} CmpOp;
-
-typedef enum AtomicOp {
- AO_XCHG,
- AO_ADD,
- AO_SUB,
- AO_AND,
- AO_OR,
- AO_XOR,
- AO_NAND,
-} AtomicOp;
-
-typedef enum MemOrder {
- MO_RELAXED,
- MO_CONSUME,
- MO_ACQUIRE,
- MO_RELEASE,
- MO_ACQ_REL,
- MO_SEQ_CST,
-} MemOrder;
-
-typedef enum IntrinKind {
- INTRIN_NONE = 0,
- INTRIN_POPCOUNT,
- INTRIN_CTZ,
- INTRIN_CLZ,
- INTRIN_BSWAP16,
- INTRIN_BSWAP32,
- INTRIN_BSWAP64,
- INTRIN_MEMCPY,
- INTRIN_MEMMOVE,
- INTRIN_MEMSET,
- INTRIN_PREFETCH,
- INTRIN_ASSUME_ALIGNED,
- INTRIN_EXPECT,
- INTRIN_UNREACHABLE,
- INTRIN_TRAP,
- INTRIN_SETJMP,
- INTRIN_LONGJMP,
- INTRIN_SADD_OVERFLOW,
- INTRIN_UADD_OVERFLOW,
- INTRIN_SSUB_OVERFLOW,
- INTRIN_USUB_OVERFLOW,
- INTRIN_SMUL_OVERFLOW,
- INTRIN_UMUL_OVERFLOW,
-} IntrinKind;
-
-typedef enum AsmDir { ASM_IN, ASM_OUT, ASM_INOUT } AsmDir;
-
-typedef struct AsmConstraint {
- const char* str;
- Sym name;
- const Type* type;
- u8 dir;
- u8 pad[3];
-} AsmConstraint;
-
-typedef enum FrameSlotKind {
- FS_LOCAL,
- FS_PARAM,
- FS_SPILL,
- FS_SRET,
- FS_ALLOCA,
-} FrameSlotKind;
-
-typedef enum FrameSlotFlag {
- FSF_NONE = 0,
- FSF_ADDR_TAKEN = 1u << 0,
- FSF_VOLATILE = 1u << 1,
-} FrameSlotFlag;
-
-typedef struct FrameSlotDesc {
- const Type* type;
- Sym name;
- SrcLoc loc;
- u32 size;
- u32 align;
- u8 kind;
- u8 pad;
- u16 flags;
-} FrameSlotDesc;
-
-typedef struct CGParamDesc {
- u32 index;
- Sym name;
- const Type* type;
- FrameSlot slot;
- const void* abi;
- const void* incoming;
- u32 nincoming;
- SrcLoc loc;
-} CGParamDesc;
-
-typedef enum CGFuncDescFlag {
- CGFD_NONE = 0,
- CGFD_NORETURN = 1u << 0,
-} CGFuncDescFlag;
-
-typedef struct CGFuncDesc {
- ObjSymId sym;
- ObjSecId text_section_id;
- u32 group_id;
- const Type* fn_type;
- const void* abi;
- const CGParamDesc* params;
- u32 nparams;
- SrcLoc loc;
- u32 flags;
- CfreeCgInlinePolicy inline_policy;
-} CGFuncDesc;
-
-typedef struct Parser Parser;
-
-CfreeCgTypeId pcg_tid(Parser*, const Type*);
-CfreeCgMemAccess pcg_mem(Parser*, const Type*);
-const Type* pcg_top_type(Parser*);
-const Type* pcg_top2_type(Parser*);
-void pcg_retag_top(Parser*, const Type*);
-void pcg_push_type(Parser*, const Type*);
-void pcg_drop_type(Parser*);
-void pcg_dup_type(Parser*);
-void pcg_swap_type(Parser*);
-int pcg_top_is_bitfield(Parser*);
-void pcg_set_top_bitfield(Parser*);
-int pcg_top_is_register(Parser*);
-void pcg_set_top_register(Parser*);
-int pcg_top_is_lvalue(Parser*);
-int pcg_top_is_modifiable_lvalue(Parser*);
-int pcg_top_is_null_ptr_const(Parser*);
-void pcg_set_top_lvalue(Parser*);
-void pcg_rot3_type(Parser*);
-int pcg_emit_enabled(Parser*);
-void pcg_codegen_suppress_push(Parser*);
-void pcg_codegen_suppress_pop(Parser*);
-
-CfreeCgIntBinOp pcg_int_binop(BinOp);
-CfreeCgFpBinOp pcg_fp_binop(BinOp);
-CfreeCgIntCmpOp pcg_int_cmp(CmpOp);
-CfreeCgFpCmpOp pcg_fp_cmp(CmpOp);
-CfreeCgAtomicOp pcg_atomic_op(AtomicOp);
-CfreeCgMemOrder pcg_mem_order(MemOrder);
-int pcg_type_is_fp(const Type*);
-int pcg_type_is_signed(const Type*);
-
-FrameSlot pcg_local(Parser*, const FrameSlotDesc*);
-FrameSlot pcg_param_slot(Parser*, u32, const FrameSlotDesc*);
-void pcg_param(Parser*, const CGParamDesc*);
-void pcg_func_begin(Parser*, const CGFuncDesc*);
-void pcg_push_int(Parser*, i64, const Type*);
-void pcg_push_float(Parser*, double, const Type*);
-void pcg_push_local_typed(Parser*, FrameSlot, const Type*);
-void pcg_push_global(Parser*, ObjSymId, const Type*);
-void pcg_load(Parser*);
-void pcg_addr(Parser*);
-void pcg_push_label_addr(Parser*, CGLabel);
-void pcg_computed_goto(Parser*, const CGLabel*, u32);
-void pcg_store(Parser*);
-void pcg_deref(Parser*, const Type*);
-
-/* ---- Lvalue auxiliary access ----
- *
- * pcg_top_lv_aux returns a mutable pointer to TOS's lvalue aux, used by
- * parse_postfix and the initializer / compound-assignment paths to fold
- * field offsets and bit-field metadata inline. Returns NULL if the parser
- * stack is empty; behavior on a non-lvalue TOS is the caller's responsibility
- * (parse_postfix has already validated lvalueness before calling). */
-PcgLvAux* pcg_top_lv_aux(Parser*);
-PcgLvAux* pcg_lv_aux_at(Parser*, u32 depth);
-
-/* ---- Lvalue chain helpers ----
- *
- * Each maps directly to the canonical encodings in doc/INDIRECT.md without
- * emitting any intermediate field / index / addr_offset CG op. Field offsets
- * and array scales are accumulated on the TOS lvalue's aux; the next
- * pcg_load / pcg_store / pcg_addr consumes them. */
-
-/* Fold `s.f` (or any path-resolved field selection) into the TOS lvalue.
- * byte_offset is the cumulative offset within the record; ty is the field
- * type; bf_* are bit-field metadata (bf_width == 0 for non-bitfields). The
- * caller is responsible for verifying TOS is an lvalue of a record type. */
-void pcg_lv_member(Parser*, i64 byte_offset, const Type* field_ty,
- u16 bf_offset, u16 bf_width, u32 bf_storage_size);
-
-/* Attach `[index]` to the TOS lvalue. PRECONDITION: the index value has just
- * been pushed onto the CG stack (and parser stack) above the lvalue base;
- * the parser stack therefore has [base_lv, index] at depth [1, 0]. This call
- * records `scale = elem_size` on the base's aux, drops the index parser
- * slot (leaving the index value on the CG stack for the eventual memop),
- * and retags the surviving slot as elem_ty (lvalue). */
-void pcg_lv_subscript(Parser*, u32 elem_size, const Type* elem_ty);
-
-/* Decay an array lvalue at TOS into a pointer-to-element rvalue. Emits
- * cfree_cg_addr (or a no-op for pointer-rvalue bases) and folds any pending
- * EA modifiers into the resulting pointer via ptr arithmetic. After return,
- * TOS is a pointer rvalue of type `*arr_ty->elem`. */
-void pcg_decay_array(Parser*, const Type* arr_ty);
-
-void pcg_binop(Parser*, BinOp);
-void pcg_unop(Parser*, UnOp);
-void pcg_cmp(Parser*, CmpOp);
-void pcg_convert(Parser*, const Type*);
-void pcg_inc_dec(Parser*, BinOp, int);
-void pcg_call(Parser*, u32, const Type*);
-void pcg_call_symbol(Parser*, CfreeCgSym, u32, const Type*);
-void pcg_ret(Parser*, int);
-void pcg_alloca(Parser*);
-void pcg_va_arg(Parser*, const Type*);
-void pcg_atomic_load(Parser*, MemOrder);
-void pcg_atomic_store(Parser*, MemOrder);
-void pcg_atomic_rmw(Parser*, AtomicOp, MemOrder);
-void pcg_atomic_cas(Parser*, MemOrder, MemOrder);
-void pcg_fence(Parser*, MemOrder);
-void pcg_intrinsic_unary_to_int(Parser*, IntrinKind);
-void pcg_intrinsic_void(Parser*, IntrinKind);
-void pcg_inline_asm(Parser*, const char*, const AsmConstraint*, u32,
- const AsmConstraint*, u32, const Sym*, u32);
-
-#define cg_set_loc(g, loc) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_set_loc((g), (loc)); \
- } while (0)
-#define cg_local(g, fsd) pcg_local(p, (fsd))
-#define cg_param(g, pd) pcg_param(p, (pd))
-#define cg_func_begin(g, fd) pcg_func_begin(p, (fd))
-#define cg_func_end(g) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_func_end((g)); \
- } while (0)
-#define cg_push_int(g, v, ty) pcg_push_int(p, (v), (ty))
-#define cg_push_float(g, v, ty) pcg_push_float(p, (v), (ty))
-#define cg_push_local_typed(g, s, ty) pcg_push_local_typed(p, (s), (ty))
-#define cg_push_global(g, sym, ty) pcg_push_global(p, (sym), (ty))
-#define cg_load(g) pcg_load(p)
-#define cg_addr(g) pcg_addr(p)
-#define cg_dup(g) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_dup((g)); \
- pcg_dup_type(p); \
- } while (0)
-#define cg_swap(g) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_swap((g)); \
- pcg_swap_type(p); \
- } while (0)
-#define cg_drop(g) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_drop((g)); \
- pcg_drop_type(p); \
- } while (0)
-#define cg_store(g) pcg_store(p)
-#define cg_deref(g, ty) pcg_deref(p, (ty))
-#define cg_top_type(g) pcg_top_type(p)
-#define cg_top2_type(g) pcg_top2_type(p)
-#define cg_retag_top(g, ty) pcg_retag_top(p, (ty))
-#define cg_binop(g, op) pcg_binop(p, (op))
-#define cg_unop(g, op) pcg_unop(p, (op))
-#define cg_cmp(g, op) pcg_cmp(p, (op))
-#define cg_convert(g, ty) pcg_convert(p, (ty))
-#define cg_inc_dec(g, op, post) pcg_inc_dec(p, (op), (post))
-#define cg_call(g, nargs, fn_type) pcg_call(p, (nargs), (fn_type))
-#define cg_ret(g, has_value) pcg_ret(p, (has_value))
-#define cg_alloca(g) pcg_alloca(p)
-#define cg_va_start_(g) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_vararg_start((g)); \
- } while (0)
-#define cg_va_end_(g) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_vararg_end((g)); \
- } while (0)
-#define cg_va_copy_(g) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_vararg_copy((g)); \
- } while (0)
-#define cg_va_arg_(g, ty) pcg_va_arg(p, (ty))
-#define cg_atomic_load(g, ord) pcg_atomic_load(p, (ord))
-#define cg_atomic_store(g, ord) pcg_atomic_store(p, (ord))
-#define cg_atomic_rmw(g, op, ord) pcg_atomic_rmw(p, (op), (ord))
-#define cg_atomic_cas(g, succ, fail) pcg_atomic_cas(p, (succ), (fail))
-#define cg_fence(g, ord) pcg_fence(p, (ord))
-#define cg_intrinsic_unary_to_int(g, k) pcg_intrinsic_unary_to_int(p, (k))
-#define cg_intrinsic_void(g, k) pcg_intrinsic_void(p, (k))
-#define cg_label_new(g) cfree_cg_label_new((g))
-#define cg_label_place(g, l) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_label_place((g), (l)); \
- } while (0)
-#define cg_jump(g, l) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_jump((g), (l)); \
- } while (0)
-#define cg_branch_true(g, l) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_branch_true((g), (l)); \
- pcg_drop_type(p); \
- } while (0)
-#define cg_branch_false(g, l) \
- do { \
- if (pcg_emit_enabled(p)) cfree_cg_branch_false((g), (l)); \
- pcg_drop_type(p); \
- } while (0)
-#define cg_inline_asm(g, tmpl, outs, nout, ins, nin, clob, nclob) \
- pcg_inline_asm(p, (tmpl), (outs), (nout), (ins), (nin), (clob), (nclob))
-
-#endif
diff --git a/lang/c/parse/parse.c b/lang/c/parse/parse.c
@@ -451,7 +451,7 @@ FrameSlot make_local_aligned(Parser* p, Sym name, const Type* type, SrcLoc loc,
fsd.align = (align_override > nat) ? align_override : nat;
fsd.kind = FS_LOCAL;
fsd.flags = FSF_NONE;
- s = cg_local(p->cg, &fsd);
+ s = pcg_local(p, &fsd);
reject_same_scope_redefinition(p, name, SEK_LOCAL, type);
e = scope_define(p, name, SEK_LOCAL, type);
e->v.slot = s;
@@ -470,15 +470,15 @@ static FrameSlot make_vla_size_slot(Parser* p) {
fsd.size = c_abi_sizeof(p->abi, fsd.type);
fsd.align = c_abi_alignof(p->abi, fsd.type);
fsd.kind = FS_LOCAL;
- return cg_local(p->cg, &fsd);
+ return pcg_local(p, &fsd);
}
static void store_top_to_size_slot(Parser* p, FrameSlot slot) {
- cg_push_local_typed(p->cg, slot, ty_size_t(p));
- cg_swap(p->cg);
+ pcg_push_local_typed(p, slot, ty_size_t(p));
+ pcg_swap(p);
coerce_top_to_lvalue(p);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_store(p);
+ pcg_drop(p);
}
static void reset_vla_pending(Parser* p) {
@@ -523,20 +523,20 @@ static int build_vla_size(Parser* p, const Type* ty, u32* count_idx,
if (count_dynamic || elem_dynamic) {
FrameSlot byte_slot = make_vla_size_slot(p);
- cg_set_loc(p->cg, loc);
+ pcg_set_loc(p, loc);
if (count_dynamic) {
- cg_push_local_typed(p->cg, count_slot, ty_size_t(p));
- cg_load(p->cg);
+ pcg_push_local_typed(p, count_slot, ty_size_t(p));
+ pcg_load(p);
} else {
- cg_push_int(p->cg, (i64)ty->arr.count, ty_size_t(p));
+ pcg_push_int(p, (i64)ty->arr.count, ty_size_t(p));
}
if (elem_dynamic) {
- cg_push_local_typed(p->cg, elem_slot, ty_size_t(p));
- cg_load(p->cg);
+ pcg_push_local_typed(p, elem_slot, ty_size_t(p));
+ pcg_load(p);
} else {
- cg_push_int(p->cg, (i64)elem_static_size, ty_size_t(p));
+ pcg_push_int(p, (i64)elem_static_size, ty_size_t(p));
}
- cg_binop(p->cg, BO_IMUL);
+ pcg_binop(p, BO_IMUL);
store_top_to_size_slot(p, byte_slot);
*bounds = add_vla_bound(p, *bounds, ty, byte_slot, count_slot);
*out_slot = byte_slot;
@@ -849,14 +849,14 @@ static void parse_init_declarator(Parser* p, const DeclSpecs* specs) {
bounds = specs->vla_bounds;
}
ptr_slot = make_local(p, name, ptr_ty, loc);
- cg_set_loc(p->cg, loc);
- cg_push_local_typed(p->cg, byte_slot, ty_size_t(p));
- cg_load(p->cg);
- cg_alloca(p->cg);
- cg_push_local_typed(p->cg, ptr_slot, ptr_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_set_loc(p, loc);
+ pcg_push_local_typed(p, byte_slot, ty_size_t(p));
+ pcg_load(p);
+ pcg_alloca(p);
+ pcg_push_local_typed(p, ptr_slot, ptr_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
sym_entry = scope_lookup(p, name);
if (sym_entry && sym_entry->kind == SEK_LOCAL) {
sym_entry->vla_byte_slot = byte_slot;
@@ -880,7 +880,7 @@ static void parse_init_declarator(Parser* p, const DeclSpecs* specs) {
SymEntry* e = scope_lookup_current(p, name);
if (e && e->kind == SEK_LOCAL) e->storage = DS_REGISTER;
}
- cg_set_loc(p->cg, loc);
+ pcg_set_loc(p, loc);
init_at(p, s, var_ty, 0, var_ty);
return;
}
@@ -890,7 +890,7 @@ static void parse_init_declarator(Parser* p, const DeclSpecs* specs) {
if (e && e->kind == SEK_LOCAL) e->storage = DS_REGISTER;
}
if (accept_punct(p, '=')) {
- cg_set_loc(p->cg, loc);
+ pcg_set_loc(p, loc);
if ((var_ty->kind == TY_STRUCT || var_ty->kind == TY_UNION) &&
!is_punct(&p->cur, '{')) {
parse_assign_expr(p);
@@ -899,19 +899,19 @@ static void parse_init_declarator(Parser* p, const DeclSpecs* specs) {
var_ty->kind == TY_UNION) {
init_at(p, s, var_ty, 0, var_ty);
} else {
- cg_push_local_typed(p->cg, s, var_ty);
+ pcg_push_local_typed(p, s, var_ty);
parse_assign_expr(p);
to_rvalue(p);
{
- const Type* rhs = cg_top_type(p->cg);
+ const Type* rhs = pcg_top_type(p);
CSemCheck chk =
c_sem_check_assignment(p->pool, var_ty, rhs, C_SEM_ASSIGN_INIT);
if (!chk.ok)
perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message)));
}
coerce_top_to_lvalue(p);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_store(p);
+ pcg_drop(p);
}
}
}
@@ -1169,8 +1169,8 @@ static void parse_function_body(Parser* p, ObjSymId fsym, const Type* fn_ty,
p->goto_labels = NULL;
p->cur_switch = NULL;
p->computed_goto_emitted = 0;
- cg_set_loc(p->cg, fname_loc);
- cg_func_begin(p->cg, &fd);
+ pcg_set_loc(p, fname_loc);
+ pcg_func_begin(p, &fd);
for (u16 i = 0; i < nparams; ++i) {
FrameSlotDesc fsd;
@@ -1199,10 +1199,10 @@ static void parse_function_body(Parser* p, ObjSymId fsym, const Type* fn_ty,
parse_compound_stmt(p);
if (fn_ty->fn.ret && fn_ty->fn.ret->kind != TY_VOID &&
fn_ty->fn.ret->kind != TY_STRUCT && fn_ty->fn.ret->kind != TY_UNION) {
- cg_push_int(p->cg, 0, fn_ty->fn.ret);
- cg_ret(p->cg, 1);
+ pcg_push_int(p, 0, fn_ty->fn.ret);
+ pcg_ret(p, 1);
} else {
- cg_ret(p->cg, 0);
+ pcg_ret(p, 0);
}
for (GotoLabel* gl = p->goto_labels; gl; gl = gl->next) {
if (!gl->placed) {
@@ -1212,7 +1212,7 @@ static void parse_function_body(Parser* p, ObjSymId fsym, const Type* fn_ty,
p->goto_labels = saved_goto_labels;
p->cur_switch = saved_switch;
p->computed_goto_emitted = saved_computed_goto;
- cg_func_end(p->cg);
+ pcg_func_end(p);
scope_pop(p);
}
diff --git a/lang/c/parse/parse.h b/lang/c/parse/parse.h
@@ -2,7 +2,7 @@
#define CFREE_LANG_C_PARSE_H
#include "decl/decl.h"
-#include "parse/cg_public_compat.h"
+#include "parse/cg_adapter.h"
#include "pp/pp.h"
/* C11 frontend. Reads preprocessed tokens, records C declarations, and drives
diff --git a/lang/c/parse/parse_expr.c b/lang/c/parse/parse_expr.c
@@ -942,11 +942,11 @@ static CConstInt cexpr_unary(Parser* p, SrcLoc loc) {
}
parse_unary(p);
{
- const Type* ty = cg_top_type(p->cg);
+ const Type* ty = pcg_top_type(p);
if (pcg_top_is_bitfield(p)) perr(p, "sizeof bit-field");
require_sizeof_type(p, ty);
i64 sz = (i64)c_abi_sizeof(p->abi, ty);
- cg_drop(p->cg);
+ pcg_drop(p);
return cint_make_u64(p, ty_size_t(p), (u64)sz);
}
}
@@ -964,9 +964,9 @@ static CConstInt cexpr_unary(Parser* p, SrcLoc loc) {
}
parse_unary(p);
{
- const Type* ty = cg_top_type(p->cg);
+ const Type* ty = pcg_top_type(p);
i64 al = (i64)c_abi_alignof(p->abi, ty);
- cg_drop(p->cg);
+ pcg_drop(p);
return cint_make_u64(p, ty_size_t(p), (u64)al);
}
}
@@ -1059,7 +1059,7 @@ static FrameSlot vla_size_slot_for_type(VLABound* bounds, const Type* ty) {
}
void to_rvalue(Parser* p) {
- const Type* t = cg_top_type(p->cg);
+ const Type* t = pcg_top_type(p);
int is_lvalue = pcg_top_is_lvalue(p);
if (t) {
if (t->kind == TY_ARRAY) {
@@ -1067,7 +1067,7 @@ void to_rvalue(Parser* p) {
return;
}
if (t->kind == TY_FUNC) {
- cg_addr(p->cg);
+ pcg_addr(p);
return;
}
if (t->kind == TY_STRUCT || t->kind == TY_UNION) {
@@ -1085,7 +1085,7 @@ void to_rvalue(Parser* p) {
return;
}
}
- if (is_lvalue) cg_load(p->cg);
+ if (is_lvalue) pcg_load(p);
}
/* ============================================================
@@ -1093,27 +1093,27 @@ void to_rvalue(Parser* p) {
* ============================================================ */
void coerce_top_to_lvalue(Parser* p) {
- const Type* src = cg_top_type(p->cg);
- const Type* dst = cg_top2_type(p->cg);
+ const Type* src = pcg_top_type(p);
+ const Type* dst = pcg_top2_type(p);
if (!src || !dst || src == dst) return;
if (type_is_arith(src) && type_is_arith(dst)) {
- cg_convert(p->cg, dst);
+ pcg_convert(p, dst);
} else if (type_is_arith(src) && type_is_ptr(dst)) {
- cg_convert(p->cg, dst);
+ pcg_convert(p, dst);
} else if (type_is_ptr(src) && type_is_ptr(dst)) {
- cg_convert(p->cg, dst);
+ pcg_convert(p, dst);
}
}
void coerce_top_to_type(Parser* p, const Type* dst) {
- const Type* src = cg_top_type(p->cg);
+ const Type* src = pcg_top_type(p);
if (!src || !dst || src == dst) return;
if (type_is_arith(src) && type_is_arith(dst)) {
- cg_convert(p->cg, dst);
+ pcg_convert(p, dst);
} else if (type_is_arith(src) && type_is_ptr(dst)) {
- cg_convert(p->cg, dst);
+ pcg_convert(p, dst);
} else if (type_is_ptr(src) && type_is_ptr(dst)) {
- cg_convert(p->cg, dst);
+ pcg_convert(p, dst);
}
}
@@ -1243,7 +1243,7 @@ static int parse_builtin_mem_call(Parser* p, Sym name, SrcLoc loc) {
sym = pcg_emit_enabled(p) ? builtin_libcall_sym(p, libname, fn_ty)
: CFREE_CG_SYM_NONE;
- cg_set_loc(p->cg, loc);
+ pcg_set_loc(p, loc);
pcg_call_symbol(p, sym, 3, fn_ty);
return 1;
}
@@ -1278,9 +1278,9 @@ static int parse_builtin_clear_cache_call(Parser* p, Sym name, SrcLoc loc) {
case CFREE_ARCH_WASM:
case CFREE_ARCH_X86_32:
case CFREE_ARCH_X86_64:
- cg_drop(p->cg);
- cg_drop(p->cg);
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_drop(p);
+ pcg_drop(p);
+ pcg_push_int(p, 0, ty_int(p));
return 1;
default:
break;
@@ -1291,9 +1291,9 @@ static int parse_builtin_clear_cache_call(Parser* p, Sym name, SrcLoc loc) {
fn_ty = type_func(p->pool, void_ty, params, 2, 0);
sym = pcg_emit_enabled(p) ? builtin_libcall_sym(p, "__clear_cache", fn_ty)
: CFREE_CG_SYM_NONE;
- cg_set_loc(p->cg, loc);
+ pcg_set_loc(p, loc);
pcg_call_symbol(p, sym, 2, fn_ty);
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_push_int(p, 0, ty_int(p));
return 1;
}
@@ -1303,7 +1303,7 @@ static MemOrder parse_atomic_mem_order(Parser* p) {
}
parse_assign_expr(p);
to_rvalue(p);
- cg_drop(p->cg);
+ pcg_drop(p);
return MO_SEQ_CST;
}
@@ -1438,7 +1438,7 @@ static FrameSlot builtin_tmp_slot(Parser* p, const Type* ty) {
fsd.size = c_abi_sizeof(p->abi, ty);
fsd.align = c_abi_alignof(p->abi, ty);
fsd.kind = FS_LOCAL;
- return cg_local(p->cg, &fsd);
+ return pcg_local(p, &fsd);
}
static int parse_builtin_overflow_call(Parser* p, Sym name, SrcLoc loc) {
@@ -1466,7 +1466,7 @@ static int parse_builtin_overflow_call(Parser* p, Sym name, SrcLoc loc) {
expect_punct(p, ',', "',' in overflow builtin");
parse_assign_expr(p);
to_rvalue(p);
- ptr_ty = cg_top_type(p->cg);
+ ptr_ty = pcg_top_type(p);
if (!ptr_ty || ptr_ty->kind != TY_PTR) {
perr(p, "overflow builtin result argument must be a pointer");
}
@@ -1477,12 +1477,12 @@ static int parse_builtin_overflow_call(Parser* p, Sym name, SrcLoc loc) {
expect_punct(p, ')', "')' after overflow builtin");
ptr_slot = builtin_tmp_slot(p, ptr_ty);
- cg_push_local_typed(p->cg, ptr_slot, ptr_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_local_typed(p, ptr_slot, ptr_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
- cg_set_loc(p->cg, loc);
+ pcg_set_loc(p, loc);
if (pcg_emit_enabled(p)) {
cfree_cg_intrinsic(p->cg, info.intrin, 2, pcg_tid(p, op_ty));
}
@@ -1492,20 +1492,20 @@ static int parse_builtin_overflow_call(Parser* p, Sym name, SrcLoc loc) {
pcg_push_type(p, bool_ty);
ov_slot = builtin_tmp_slot(p, bool_ty);
- cg_push_local_typed(p->cg, ov_slot, bool_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
-
- cg_push_local_typed(p->cg, ptr_slot, ptr_ty);
- cg_load(p->cg);
- cg_deref(p->cg, out_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
-
- cg_push_local_typed(p->cg, ov_slot, bool_ty);
- cg_load(p->cg);
+ pcg_push_local_typed(p, ov_slot, bool_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
+
+ pcg_push_local_typed(p, ptr_slot, ptr_ty);
+ pcg_load(p);
+ pcg_deref(p, out_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
+
+ pcg_push_local_typed(p, ov_slot, bool_ty);
+ pcg_load(p);
return 1;
}
@@ -1517,15 +1517,15 @@ static int parse_builtin_isnan_call(Parser* p, Sym name, SrcLoc loc) {
expect_punct(p, '(', "'(' after __builtin_isnan");
parse_assign_expr(p);
to_rvalue(p);
- arg_ty = cg_top_type(p->cg);
+ arg_ty = pcg_top_type(p);
if (!type_is_fp(arg_ty)) {
perr(p, "__builtin_isnan argument must have floating type");
}
expect_punct(p, ')', "')' after __builtin_isnan");
- cg_set_loc(p->cg, loc);
- cg_dup(p->cg);
- cg_cmp(p->cg, CMP_NE);
+ pcg_set_loc(p, loc);
+ pcg_dup(p);
+ pcg_cmp(p, CMP_NE);
return 1;
}
@@ -1553,8 +1553,8 @@ static int parse_builtin_inf_call(Parser* p, Sym name, SrcLoc loc) {
advance(p); /* IDENT */
expect_punct(p, '(', "'(' after floating builtin");
expect_punct(p, ')', "')' after floating builtin");
- cg_set_loc(p->cg, loc);
- cg_push_float(p->cg, __builtin_inf(), ty);
+ pcg_set_loc(p, loc);
+ pcg_push_float(p, __builtin_inf(), ty);
return 1;
}
@@ -1573,45 +1573,45 @@ static int parse_builtin_fabs_call(Parser* p, Sym name, SrcLoc loc) {
expect_punct(p, '(', "'(' after __builtin_fabs");
parse_assign_expr(p);
to_rvalue(p);
- if (!type_is_fp(cg_top_type(p->cg))) {
+ if (!type_is_fp(pcg_top_type(p))) {
perr(p, "__builtin_fabs argument must have floating type");
}
coerce_top_to_type(p, ty);
expect_punct(p, ')', "')' after __builtin_fabs");
slot = builtin_tmp_slot(p, ty);
- cg_push_local_typed(p->cg, slot, ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
-
- cg_set_loc(p->cg, loc);
- cg_push_local_typed(p->cg, slot, ty);
- cg_load(p->cg);
- cg_push_float(p->cg, 0.0, ty);
- cg_cmp(p->cg, CMP_LT_F);
- L_nonneg = cg_label_new(p->cg);
- cg_branch_false(p->cg, L_nonneg);
- cg_push_local_typed(p->cg, slot, ty);
- cg_push_local_typed(p->cg, slot, ty);
- cg_load(p->cg);
- cg_unop(p->cg, UO_NEG);
- cg_store(p->cg);
- cg_drop(p->cg);
- cg_label_place(p->cg, L_nonneg);
- cg_push_local_typed(p->cg, slot, ty);
- cg_load(p->cg);
- cg_push_float(p->cg, 0.0, ty);
- cg_cmp(p->cg, CMP_EQ);
- L_nonzero = cg_label_new(p->cg);
- cg_branch_false(p->cg, L_nonzero);
- cg_push_local_typed(p->cg, slot, ty);
- cg_push_float(p->cg, 0.0, ty);
- cg_store(p->cg);
- cg_drop(p->cg);
- cg_label_place(p->cg, L_nonzero);
- cg_push_local_typed(p->cg, slot, ty);
- cg_load(p->cg);
+ pcg_push_local_typed(p, slot, ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
+
+ pcg_set_loc(p, loc);
+ pcg_push_local_typed(p, slot, ty);
+ pcg_load(p);
+ pcg_push_float(p, 0.0, ty);
+ pcg_cmp(p, CMP_LT_F);
+ L_nonneg = pcg_label_new(p);
+ pcg_branch_false(p, L_nonneg);
+ pcg_push_local_typed(p, slot, ty);
+ pcg_push_local_typed(p, slot, ty);
+ pcg_load(p);
+ pcg_unop(p, UO_NEG);
+ pcg_store(p);
+ pcg_drop(p);
+ pcg_label_place(p, L_nonneg);
+ pcg_push_local_typed(p, slot, ty);
+ pcg_load(p);
+ pcg_push_float(p, 0.0, ty);
+ pcg_cmp(p, CMP_EQ);
+ L_nonzero = pcg_label_new(p);
+ pcg_branch_false(p, L_nonzero);
+ pcg_push_local_typed(p, slot, ty);
+ pcg_push_float(p, 0.0, ty);
+ pcg_store(p);
+ pcg_drop(p);
+ pcg_label_place(p, L_nonzero);
+ pcg_push_local_typed(p, slot, ty);
+ pcg_load(p);
return 1;
}
@@ -1649,7 +1649,7 @@ static int parse_builtin_abs_call(Parser* p, Sym name, SrcLoc loc) {
fn_ty = type_func(p->pool, int_ty, params, 1, 0);
sym = pcg_emit_enabled(p) ? builtin_libcall_sym(p, libname, fn_ty)
: CFREE_CG_SYM_NONE;
- cg_set_loc(p->cg, loc);
+ pcg_set_loc(p, loc);
pcg_call_symbol(p, sym, 1, fn_ty);
return 1;
}
@@ -1695,7 +1695,7 @@ static int try_parse_builtin_call(Parser* p) {
u32 off = 0;
(void)offsetof_designator(p, root, &off);
expect_punct(p, ')', "')' after __builtin_offsetof");
- cg_push_int(p->cg, (i64)off, ty_size_t(p));
+ pcg_push_int(p, (i64)off, ty_size_t(p));
return 1;
}
@@ -1704,7 +1704,7 @@ static int try_parse_builtin_call(Parser* p) {
to_rvalue(p);
expect_punct(p, ',', "',' in __builtin_expect");
parse_assign_expr(p);
- cg_drop(p->cg);
+ pcg_drop(p);
expect_punct(p, ')', "')' after __builtin_expect");
return 1;
}
@@ -1713,8 +1713,8 @@ static int try_parse_builtin_call(Parser* p) {
parse_assign_expr(p);
to_rvalue(p);
expect_punct(p, ')', "')' after __builtin_alloca");
- cg_set_loc(p->cg, loc);
- cg_alloca(p->cg);
+ pcg_set_loc(p, loc);
+ pcg_alloca(p);
return 1;
}
@@ -1722,8 +1722,8 @@ static int try_parse_builtin_call(Parser* p) {
parse_assign_expr(p);
to_rvalue(p);
expect_punct(p, ')', "')' after __builtin_ctz");
- cg_set_loc(p->cg, loc);
- cg_intrinsic_unary_to_int(p->cg, INTRIN_CTZ);
+ pcg_set_loc(p, loc);
+ pcg_intrinsic_unary_to_int(p, INTRIN_CTZ);
return 1;
}
@@ -1731,71 +1731,71 @@ static int try_parse_builtin_call(Parser* p) {
parse_assign_expr(p);
to_rvalue(p);
expect_punct(p, ')', "')' after __builtin_clz");
- cg_set_loc(p->cg, loc);
+ pcg_set_loc(p, loc);
/* The operand carries its own type, which drives the sf bit on
* aarch64 / REX.W on x64 / sf on rv64. Whether the caller used the
* `l` / `ll` suffix only changes the C-level type the user wrote;
* cfree picks the instruction width from the value type. */
- cg_intrinsic_unary_to_int(p->cg, INTRIN_CLZ);
+ pcg_intrinsic_unary_to_int(p, INTRIN_CLZ);
return 1;
}
if (name == p->sym_b_trap || name == p->sym_b_unreachable) {
expect_punct(p, ')', "')' after __builtin_trap/unreachable");
- cg_set_loc(p->cg, loc);
- cg_intrinsic_void(p->cg,
+ pcg_set_loc(p, loc);
+ pcg_intrinsic_void(p,
name == p->sym_b_trap ? INTRIN_TRAP : INTRIN_UNREACHABLE);
/* Both are noreturn at the C level. Push a dummy `int 0` so callers
* that consume an expression value (e.g. ternary, comma) don't see
* an empty stack — the dead value will be folded out. */
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_push_int(p, 0, ty_int(p));
return 1;
}
if (name == p->sym_b_va_start) {
parse_assign_expr(p);
- cg_addr(p->cg);
+ pcg_addr(p);
expect_punct(p, ',', "',' in __builtin_va_start");
parse_assign_expr(p);
- cg_drop(p->cg);
+ pcg_drop(p);
expect_punct(p, ')', "')' after __builtin_va_start");
- cg_set_loc(p->cg, loc);
- cg_va_start_(p->cg);
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_set_loc(p, loc);
+ pcg_va_start(p);
+ pcg_push_int(p, 0, ty_int(p));
return 1;
}
if (name == p->sym_b_va_end) {
parse_assign_expr(p);
- cg_addr(p->cg);
+ pcg_addr(p);
expect_punct(p, ')', "')' after __builtin_va_end");
- cg_set_loc(p->cg, loc);
- cg_va_end_(p->cg);
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_set_loc(p, loc);
+ pcg_va_end(p);
+ pcg_push_int(p, 0, ty_int(p));
return 1;
}
if (name == p->sym_b_va_copy) {
parse_assign_expr(p);
- cg_addr(p->cg);
+ pcg_addr(p);
expect_punct(p, ',', "',' in __builtin_va_copy");
parse_assign_expr(p);
- cg_addr(p->cg);
+ pcg_addr(p);
expect_punct(p, ')', "')' after __builtin_va_copy");
- cg_set_loc(p->cg, loc);
- cg_va_copy_(p->cg);
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_set_loc(p, loc);
+ pcg_va_copy(p);
+ pcg_push_int(p, 0, ty_int(p));
return 1;
}
if (name == p->sym_b_va_arg) {
parse_assign_expr(p);
- cg_addr(p->cg);
+ pcg_addr(p);
expect_punct(p, ',', "',' in __builtin_va_arg");
const Type* ty = parse_type_name(p);
expect_punct(p, ')', "')' after __builtin_va_arg");
- cg_set_loc(p->cg, loc);
- cg_va_arg_(p->cg, ty);
+ pcg_set_loc(p, loc);
+ pcg_va_arg(p, ty);
return 1;
}
@@ -1805,8 +1805,8 @@ static int try_parse_builtin_call(Parser* p) {
expect_punct(p, ',', "',' in __atomic_load_n");
MemOrder ord = parse_atomic_mem_order(p);
expect_punct(p, ')', "')' after __atomic_load_n");
- cg_set_loc(p->cg, loc);
- cg_atomic_load(p->cg, ord);
+ pcg_set_loc(p, loc);
+ pcg_atomic_load(p, ord);
return 1;
}
@@ -1814,7 +1814,7 @@ static int try_parse_builtin_call(Parser* p) {
parse_assign_expr(p);
to_rvalue(p);
const Type* val_ty =
- atomic_pointee_type(p, cg_top_type(p->cg), "__atomic_store_n");
+ atomic_pointee_type(p, pcg_top_type(p), "__atomic_store_n");
expect_punct(p, ',', "',' in __atomic_store_n");
parse_assign_expr(p);
to_rvalue(p);
@@ -1822,18 +1822,18 @@ static int try_parse_builtin_call(Parser* p) {
expect_punct(p, ',', "',' in __atomic_store_n");
MemOrder ord = parse_atomic_mem_order(p);
expect_punct(p, ')', "')' after __atomic_store_n");
- cg_set_loc(p->cg, loc);
- cg_atomic_store(p->cg, ord);
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_set_loc(p, loc);
+ pcg_atomic_store(p, ord);
+ pcg_push_int(p, 0, ty_int(p));
return 1;
}
if (name == p->sym_a_thread_fence || name == p->sym_a_signal_fence) {
MemOrder ord = parse_atomic_mem_order(p);
expect_punct(p, ')', "')' after atomic fence");
- cg_set_loc(p->cg, loc);
- cg_fence(p->cg, ord);
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_set_loc(p, loc);
+ pcg_fence(p, ord);
+ pcg_push_int(p, 0, ty_int(p));
return 1;
}
@@ -1842,22 +1842,22 @@ static int try_parse_builtin_call(Parser* p) {
expect_punct(p, ',', "',' in atomic lock-free builtin");
parse_assign_expr(p);
to_rvalue(p);
- cg_drop(p->cg);
+ pcg_drop(p);
expect_punct(p, ')', "')' after atomic lock-free builtin");
- cg_push_int(p->cg, atomic_lock_free_for_const_size(p, size), ty_int(p));
+ pcg_push_int(p, atomic_lock_free_for_const_size(p, size), ty_int(p));
return 1;
}
if (name == p->sym_a_cas_n) {
parse_assign_expr(p);
to_rvalue(p); /* ptr */
- const Type* obj_ty = atomic_pointee_type(p, cg_top_type(p->cg),
+ const Type* obj_ty = atomic_pointee_type(p, pcg_top_type(p),
"__atomic_compare_exchange_n");
expect_punct(p, ',', "',' in __atomic_compare_exchange_n");
parse_assign_expr(p);
to_rvalue(p); /* &expected */
- const Type* eptr_ty = cg_top_type(p->cg);
+ const Type* eptr_ty = pcg_top_type(p);
if (!eptr_ty || eptr_ty->kind != TY_PTR) {
perr(p, "__atomic_compare_exchange_n: arg 2 must be a pointer");
}
@@ -1872,16 +1872,16 @@ static int try_parse_builtin_call(Parser* p) {
fsd.size = 8;
fsd.align = 8;
fsd.kind = FS_LOCAL;
- FrameSlot eslot = cg_local(p->cg, &fsd);
- cg_push_local_typed(p->cg, eslot, eptr_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ FrameSlot eslot = pcg_local(p, &fsd);
+ pcg_push_local_typed(p, eslot, eptr_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
- cg_push_local_typed(p->cg, eslot, eptr_ty);
- cg_load(p->cg);
- cg_deref(p->cg, val_ty);
- cg_load(p->cg);
+ pcg_push_local_typed(p, eslot, eptr_ty);
+ pcg_load(p);
+ pcg_deref(p, val_ty);
+ pcg_load(p);
expect_punct(p, ',', "',' in __atomic_compare_exchange_n");
parse_assign_expr(p);
@@ -1896,21 +1896,21 @@ static int try_parse_builtin_call(Parser* p) {
MemOrder fail = parse_atomic_mem_order(p);
expect_punct(p, ')', "')' after __atomic_compare_exchange_n");
- cg_set_loc(p->cg, loc);
- cg_atomic_cas(p->cg, succ, fail);
+ pcg_set_loc(p, loc);
+ pcg_atomic_cas(p, succ, fail);
- const Type* ok_ty = cg_top_type(p->cg);
+ const Type* ok_ty = pcg_top_type(p);
FrameSlotDesc okd;
memset(&okd, 0, sizeof okd);
okd.type = ok_ty;
okd.size = 4;
okd.align = 4;
okd.kind = FS_LOCAL;
- FrameSlot okslot = cg_local(p->cg, &okd);
- cg_push_local_typed(p->cg, okslot, ok_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ FrameSlot okslot = pcg_local(p, &okd);
+ pcg_push_local_typed(p, okslot, ok_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
FrameSlotDesc pd;
memset(&pd, 0, sizeof pd);
@@ -1918,27 +1918,27 @@ static int try_parse_builtin_call(Parser* p) {
pd.size = c_abi_sizeof(p->abi, val_ty);
pd.align = c_abi_alignof(p->abi, val_ty);
pd.kind = FS_LOCAL;
- FrameSlot pslot = cg_local(p->cg, &pd);
- cg_push_local_typed(p->cg, pslot, val_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
-
- cg_push_local_typed(p->cg, okslot, ok_ty);
- cg_load(p->cg);
- CGLabel L_done = cg_label_new(p->cg);
- cg_branch_true(p->cg, L_done);
- cg_push_local_typed(p->cg, eslot, eptr_ty);
- cg_load(p->cg);
- cg_deref(p->cg, val_ty);
- cg_push_local_typed(p->cg, pslot, val_ty);
- cg_load(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
- cg_label_place(p->cg, L_done);
-
- cg_push_local_typed(p->cg, okslot, ok_ty);
- cg_load(p->cg);
+ FrameSlot pslot = pcg_local(p, &pd);
+ pcg_push_local_typed(p, pslot, val_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
+
+ pcg_push_local_typed(p, okslot, ok_ty);
+ pcg_load(p);
+ CGLabel L_done = pcg_label_new(p);
+ pcg_branch_true(p, L_done);
+ pcg_push_local_typed(p, eslot, eptr_ty);
+ pcg_load(p);
+ pcg_deref(p, val_ty);
+ pcg_push_local_typed(p, pslot, val_ty);
+ pcg_load(p);
+ pcg_store(p);
+ pcg_drop(p);
+ pcg_label_place(p, L_done);
+
+ pcg_push_local_typed(p, okslot, ok_ty);
+ pcg_load(p);
return 1;
}
@@ -1964,7 +1964,7 @@ static int try_parse_builtin_call(Parser* p) {
parse_assign_expr(p);
to_rvalue(p);
const Type* val_ty =
- atomic_pointee_type(p, cg_top_type(p->cg), "__atomic read-modify-write");
+ atomic_pointee_type(p, pcg_top_type(p), "__atomic read-modify-write");
expect_punct(p, ',', "',' in atomic builtin");
parse_assign_expr(p);
to_rvalue(p);
@@ -1972,8 +1972,8 @@ static int try_parse_builtin_call(Parser* p) {
expect_punct(p, ',', "',' in atomic builtin");
MemOrder ord = parse_atomic_mem_order(p);
expect_punct(p, ')', "')' after atomic builtin");
- cg_set_loc(p->cg, loc);
- cg_atomic_rmw(p->cg, op, ord);
+ pcg_set_loc(p, loc);
+ pcg_atomic_rmw(p, op, ord);
return 1;
}
@@ -1987,14 +1987,14 @@ static void parse_primary(Parser* p) {
i64 v = parse_int_literal(p, &t);
const Type* lty = int_literal_type(p, &t);
advance(p);
- cg_push_int(p->cg, v, lty);
+ pcg_push_int(p, v, lty);
return;
}
if (t.kind == TOK_FLT) {
double v = parse_float_literal(p, &t);
const Type* lty = float_literal_type(p, &t);
advance(p);
- cg_push_float(p->cg, v, lty);
+ pcg_push_float(p, v, lty);
return;
}
if (is_punct(&t, '(')) {
@@ -2044,7 +2044,7 @@ static void parse_primary(Parser* p) {
advance(p);
const Type* char_ty = type_prim(p->pool, TY_CHAR);
const Type* arr_ty = type_array(p->pool, char_ty, (u32)(nlen + 1u), 0);
- cg_push_global(p->cg, sym, arr_ty);
+ pcg_push_global(p, sym, arr_ty);
return;
}
e = scope_lookup(p, t.v.ident);
@@ -2058,7 +2058,7 @@ static void parse_primary(Parser* p) {
advance(p);
switch (e->kind) {
case SEK_LOCAL:
- cg_push_local_typed(p->cg, e->v.slot, e->type);
+ pcg_push_local_typed(p, e->v.slot, e->type);
if (e->storage == DS_REGISTER) pcg_set_top_register(p);
if (e->vla_byte_slot != FRAME_SLOT_NONE) {
p->last_pushed_vla_slot = e->vla_byte_slot;
@@ -2069,10 +2069,10 @@ static void parse_primary(Parser* p) {
return;
case SEK_GLOBAL:
case SEK_FUNC:
- cg_push_global(p->cg, e->v.sym, e->type);
+ pcg_push_global(p, e->v.sym, e->type);
return;
case SEK_ENUM_CST:
- cg_push_int(p->cg, e->v.enum_value, e->type);
+ pcg_push_int(p, e->v.enum_value, e->type);
return;
case SEK_TYPEDEF:
default:
@@ -2083,7 +2083,7 @@ static void parse_primary(Parser* p) {
i64 v = decode_char_literal(p, &t);
const Type* lty = char_literal_type(p, &t);
advance(p);
- cg_push_int(p->cg, v, lty);
+ pcg_push_int(p, v, lty);
return;
}
if (t.kind == TOK_STR) {
@@ -2098,7 +2098,7 @@ static void parse_primary(Parser* p) {
{
const Type* arr_ty =
type_array(p->pool, elem_ty, elem_size ? (u32)(n / elem_size) : 0, 0);
- cg_push_global(p->cg, sym, arr_ty);
+ pcg_push_global(p, sym, arr_ty);
}
return;
}
@@ -2192,10 +2192,10 @@ static void parse_postfix(Parser* p) {
if (!pcg_top_is_modifiable_lvalue(p)) {
perr(p, "increment/decrement requires modifiable lvalue");
}
- if (!c_type_is_scalar(cg_top_type(p->cg))) {
+ if (!c_type_is_scalar(pcg_top_type(p))) {
perr(p, "increment/decrement requires scalar operand");
}
- cg_inc_dec(p->cg, BO_IADD, /*post=*/1);
+ pcg_inc_dec(p, BO_IADD, /*post=*/1);
continue;
}
if (is_punct(&t, P_DEC)) {
@@ -2203,21 +2203,21 @@ static void parse_postfix(Parser* p) {
if (!pcg_top_is_modifiable_lvalue(p)) {
perr(p, "increment/decrement requires modifiable lvalue");
}
- if (!c_type_is_scalar(cg_top_type(p->cg))) {
+ if (!c_type_is_scalar(pcg_top_type(p))) {
perr(p, "increment/decrement requires scalar operand");
}
- cg_inc_dec(p->cg, BO_ISUB, /*post=*/1);
+ pcg_inc_dec(p, BO_ISUB, /*post=*/1);
continue;
}
if (is_punct(&t, '(')) {
- const Type* top = cg_top_type(p->cg);
+ const Type* top = pcg_top_type(p);
const Type* fn_type;
if (top && top->kind == TY_FUNC) {
fn_type = top;
} else if (top && top->kind == TY_PTR && top->ptr.pointee &&
top->ptr.pointee->kind == TY_FUNC) {
fn_type = top->ptr.pointee;
- if (pcg_top_is_lvalue(p)) cg_load(p->cg);
+ if (pcg_top_is_lvalue(p)) pcg_load(p);
} else {
perr(p, "called object is not a function");
}
@@ -2231,7 +2231,7 @@ static void parse_postfix(Parser* p) {
to_rvalue(p);
if (param_ty) {
CSemCheck chk = c_sem_check_assignment(
- p->pool, param_ty, cg_top_type(p->cg), C_SEM_ASSIGN_EXPR);
+ p->pool, param_ty, pcg_top_type(p), C_SEM_ASSIGN_EXPR);
if (!chk.ok)
perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message)));
coerce_top_to_type(p, param_ty);
@@ -2247,23 +2247,23 @@ static void parse_postfix(Parser* p) {
if (fn_type->fn.variadic && nargs < fn_type->fn.nparams) {
perr(p, "too few arguments to variadic function");
}
- cg_call(p->cg, nargs, fn_type);
+ pcg_call(p, nargs, fn_type);
if (fn_type->fn.ret && fn_type->fn.ret->kind == TY_VOID) {
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_push_int(p, 0, ty_int(p));
}
continue;
}
if (is_punct(&t, '[')) {
- const Type* lt0 = cg_top_type(p->cg);
+ const Type* lt0 = pcg_top_type(p);
advance(p); /* '[' */
if (lt0 && lt0->kind == TY_ARRAY) {
decay_array_to_pointer(p, lt0);
} else if (lt0 && lt0->kind == TY_PTR) {
- if (pcg_top_is_lvalue(p)) cg_load(p->cg);
+ if (pcg_top_is_lvalue(p)) pcg_load(p);
}
parse_expr(p);
{
- const Type* it0 = cg_top_type(p->cg);
+ const Type* it0 = pcg_top_type(p);
if (it0 && it0->kind == TY_ARRAY) {
decay_array_to_pointer(p, it0);
} else {
@@ -2272,13 +2272,13 @@ static void parse_postfix(Parser* p) {
}
expect_punct(p, ']', "']' after subscript");
{
- const Type* lt = cg_top2_type(p->cg);
- const Type* it = cg_top_type(p->cg);
+ const Type* lt = pcg_top2_type(p);
+ const Type* it = pcg_top_type(p);
const Type* elem;
if (lt && lt->kind == TY_PTR && type_is_int(it)) {
elem = lt->ptr.pointee;
} else if (it && it->kind == TY_PTR && type_is_int(lt)) {
- cg_swap(p->cg);
+ pcg_swap(p);
elem = it->ptr.pointee;
} else {
perr(p, "invalid subscript: needs one pointer and one integer");
@@ -2288,11 +2288,11 @@ static void parse_postfix(Parser* p) {
{
FrameSlot elem_vla_slot = vla_size_slot_for_type(vla_bounds, elem);
if (elem_vla_slot != FRAME_SLOT_NONE) {
- cg_push_local_typed(p->cg, elem_vla_slot, ty_size_t(p));
- cg_load(p->cg);
- cg_binop(p->cg, BO_IMUL);
- cg_binop(p->cg, BO_IADD);
- cg_deref(p->cg, elem);
+ pcg_push_local_typed(p, elem_vla_slot, ty_size_t(p));
+ pcg_load(p);
+ pcg_binop(p, BO_IMUL);
+ pcg_binop(p, BO_IADD);
+ pcg_deref(p, elem);
p->last_pushed_vla_slot = elem_vla_slot;
p->last_pushed_vla_bounds = vla_bounds;
} else {
@@ -2304,7 +2304,7 @@ static void parse_postfix(Parser* p) {
continue;
}
if (is_punct(&t, '.')) {
- const Type* lt = cg_top_type(p->cg);
+ const Type* lt = pcg_top_type(p);
Sym mname;
const Type* mty = NULL;
const Field* mf = NULL;
@@ -2336,7 +2336,7 @@ static void parse_postfix(Parser* p) {
u32 depth = 0;
advance(p); /* `->` */
to_rvalue(p);
- lt0 = cg_top_type(p->cg);
+ lt0 = pcg_top_type(p);
if (!lt0 || lt0->kind != TY_PTR) {
perr(p, "'->' requires a pointer operand");
}
@@ -2351,7 +2351,7 @@ static void parse_postfix(Parser* p) {
advance(p);
if (!find_record_member_path(p, rec_ty, mname, &mty, path, &depth, &mf))
perr(p, "no such member");
- cg_deref(p->cg, rec_ty);
+ pcg_deref(p, rec_ty);
cg_record_member_path(p, mty, path, depth, mf);
continue;
}
@@ -2382,32 +2382,32 @@ void parse_unary(Parser* p) {
fsd.align = c_abi_alignof(p->abi, lit_ty);
fsd.kind = FS_LOCAL;
fsd.flags = FSF_NONE;
- slot = cg_local(p->cg, &fsd);
+ slot = pcg_local(p, &fsd);
if (lit_ty && (lit_ty->kind == TY_ARRAY || lit_ty->kind == TY_STRUCT ||
lit_ty->kind == TY_UNION)) {
init_at(p, slot, lit_ty, 0, lit_ty);
} else {
init_at(p, slot, lit_ty, 0, lit_ty);
}
- cg_push_local_typed(p->cg, slot, lit_ty);
+ pcg_push_local_typed(p, slot, lit_ty);
return;
}
parse_unary(p);
to_rvalue(p);
- src = cg_top_type(p->cg);
+ src = pcg_top_type(p);
if (dst && dst->kind == TY_VOID) {
- cg_drop(p->cg);
- cg_push_int(p->cg, 0, ty_int(p));
+ pcg_drop(p);
+ pcg_push_int(p, 0, ty_int(p));
return;
}
if (!c_type_is_scalar(dst) || !c_type_is_scalar(src)) {
perr(p, "cast requires scalar type");
}
if (src && src->kind == TY_PTR && dst->kind == TY_PTR) {
- cg_convert(p->cg, dst);
+ pcg_convert(p, dst);
return;
}
- cg_convert(p->cg, dst);
+ pcg_convert(p, dst);
return;
}
}
@@ -2415,34 +2415,34 @@ void parse_unary(Parser* p) {
advance(p);
parse_unary(p);
to_rvalue(p);
- require_arith(p, cg_top_type(p->cg), "unary '+'");
+ require_arith(p, pcg_top_type(p), "unary '+'");
return;
}
if (is_punct(&t, '-')) {
advance(p);
parse_unary(p);
to_rvalue(p);
- require_arith(p, cg_top_type(p->cg), "unary '-'");
- cg_unop(p->cg, UO_NEG);
+ require_arith(p, pcg_top_type(p), "unary '-'");
+ pcg_unop(p, UO_NEG);
return;
}
if (is_punct(&t, '!')) {
advance(p);
parse_unary(p);
to_rvalue(p);
- require_scalar(p, cg_top_type(p->cg), "unary '!'");
- cg_push_int(p->cg, 0, ty_int(p));
- cg_cmp(p->cg, CMP_EQ);
+ require_scalar(p, pcg_top_type(p), "unary '!'");
+ pcg_push_int(p, 0, ty_int(p));
+ pcg_cmp(p, CMP_EQ);
return;
}
if (is_punct(&t, '~')) {
advance(p);
parse_unary(p);
to_rvalue(p);
- if (!type_is_int(cg_top_type(p->cg))) {
+ if (!type_is_int(pcg_top_type(p))) {
perr(p, "unary '~' requires integer operand");
}
- cg_unop(p->cg, UO_BNOT);
+ pcg_unop(p, UO_BNOT);
return;
}
if (is_punct(&t, P_AND)) {
@@ -2463,13 +2463,13 @@ void parse_unary(Parser* p) {
advance(p);
parse_unary(p);
if (!pcg_top_is_lvalue(p) &&
- !(cg_top_type(p->cg) && cg_top_type(p->cg)->kind == TY_FUNC)) {
+ !(pcg_top_type(p) && pcg_top_type(p)->kind == TY_FUNC)) {
perr(p, "address-of requires lvalue operand");
}
if (pcg_top_is_bitfield(p)) perr(p, "cannot take address of bit-field");
if (pcg_top_is_register(p))
perr(p, "cannot take address of register object");
- cg_addr(p->cg);
+ pcg_addr(p);
return;
}
if (is_punct(&t, '*')) {
@@ -2478,7 +2478,7 @@ void parse_unary(Parser* p) {
advance(p);
parse_unary(p);
to_rvalue(p);
- pty = cg_top_type(p->cg);
+ pty = pcg_top_type(p);
if (!pty || pty->kind != TY_PTR) {
perr(p, "indirection requires pointer operand");
}
@@ -2486,7 +2486,7 @@ void parse_unary(Parser* p) {
if (pointee && pointee->kind == TY_VOID) {
perr(p, "dereferencing pointer to incomplete type");
}
- cg_deref(p->cg, pointee);
+ pcg_deref(p, pointee);
return;
}
if (is_punct(&t, P_INC) || is_punct(&t, P_DEC)) {
@@ -2496,10 +2496,10 @@ void parse_unary(Parser* p) {
if (!pcg_top_is_modifiable_lvalue(p)) {
perr(p, "increment/decrement requires modifiable lvalue");
}
- if (!c_type_is_scalar(cg_top_type(p->cg))) {
+ if (!c_type_is_scalar(pcg_top_type(p))) {
perr(p, "increment/decrement requires scalar operand");
}
- cg_inc_dec(p->cg, bop, /*post=*/0);
+ pcg_inc_dec(p, bop, /*post=*/0);
return;
}
if (is_kw(p, &t, KW_SIZEOF)) {
@@ -2516,28 +2516,28 @@ void parse_unary(Parser* p) {
p->last_pushed_vla_slot = FRAME_SLOT_NONE;
pcg_codegen_suppress_push(p);
parse_unary(p);
- ty = cg_top_type(p->cg);
+ ty = pcg_top_type(p);
vla_slot = p->last_pushed_vla_slot;
if (pcg_top_is_bitfield(p)) perr(p, "sizeof bit-field");
- cg_drop(p->cg);
+ pcg_drop(p);
pcg_codegen_suppress_pop(p);
}
} else {
p->last_pushed_vla_slot = FRAME_SLOT_NONE;
pcg_codegen_suppress_push(p);
parse_unary(p);
- ty = cg_top_type(p->cg);
+ ty = pcg_top_type(p);
vla_slot = p->last_pushed_vla_slot;
if (pcg_top_is_bitfield(p)) perr(p, "sizeof bit-field");
- cg_drop(p->cg);
+ pcg_drop(p);
pcg_codegen_suppress_pop(p);
}
if (vla_slot != FRAME_SLOT_NONE) {
- cg_push_local_typed(p->cg, vla_slot, ty_size_t(p));
- cg_load(p->cg);
+ pcg_push_local_typed(p, vla_slot, ty_size_t(p));
+ pcg_load(p);
} else {
require_sizeof_type(p, ty);
- cg_push_int(p->cg, (i64)c_abi_sizeof(p->abi, ty), ty_size_t(p));
+ pcg_push_int(p, (i64)c_abi_sizeof(p->abi, ty), ty_size_t(p));
}
return;
}
@@ -2547,8 +2547,8 @@ void parse_unary(Parser* p) {
pcg_codegen_suppress_push(p);
parse_assign_expr(p);
to_rvalue(p);
- const Type* ctl_ty = cg_top_type(p->cg);
- cg_drop(p->cg);
+ const Type* ctl_ty = pcg_top_type(p);
+ pcg_drop(p);
pcg_codegen_suppress_pop(p);
expect_punct(p, ',', "','");
int emitted = 0;
@@ -2706,11 +2706,11 @@ void parse_unary(Parser* p) {
ty = parse_type_name(p);
} else {
parse_unary(p);
- ty = cg_top_type(p->cg);
- cg_drop(p->cg);
+ ty = pcg_top_type(p);
+ pcg_drop(p);
}
expect_punct(p, ')', "')'");
- cg_push_int(p->cg, (i64)c_abi_alignof(p->abi, ty), ty_size_t(p));
+ pcg_push_int(p, (i64)c_abi_alignof(p->abi, ty), ty_size_t(p));
return;
}
parse_postfix(p);
@@ -2737,10 +2737,10 @@ static const Type* common_fp_type(Parser* p, const Type* a, const Type* b) {
}
static void emit_fp_binop(Parser* p, BinOp bop, const Type* common) {
- if (cg_top_type(p->cg) != common) cg_convert(p->cg, common);
- cg_swap(p->cg);
- if (cg_top_type(p->cg) != common) cg_convert(p->cg, common);
- cg_swap(p->cg);
+ if (pcg_top_type(p) != common) pcg_convert(p, common);
+ pcg_swap(p);
+ if (pcg_top_type(p) != common) pcg_convert(p, common);
+ pcg_swap(p);
BinOp fop;
switch (bop) {
case BO_IADD:
@@ -2759,22 +2759,22 @@ static void emit_fp_binop(Parser* p, BinOp bop, const Type* common) {
perr(p, "operator does not apply to floating types");
return;
}
- cg_binop(p->cg, fop);
+ pcg_binop(p, fop);
}
static void coerce_fp_cmp_operands(Parser* p, const Type* common) {
- if (cg_top_type(p->cg) != common) cg_convert(p->cg, common);
- cg_swap(p->cg);
- if (cg_top_type(p->cg) != common) cg_convert(p->cg, common);
- cg_swap(p->cg);
+ if (pcg_top_type(p) != common) pcg_convert(p, common);
+ pcg_swap(p);
+ if (pcg_top_type(p) != common) pcg_convert(p, common);
+ pcg_swap(p);
}
static void coerce_arith_operands(Parser* p, const Type* common) {
if (!common) return;
- if (cg_top_type(p->cg) != common) cg_convert(p->cg, common);
- cg_swap(p->cg);
- if (cg_top_type(p->cg) != common) cg_convert(p->cg, common);
- cg_swap(p->cg);
+ if (pcg_top_type(p) != common) pcg_convert(p, common);
+ pcg_swap(p);
+ if (pcg_top_type(p) != common) pcg_convert(p, common);
+ pcg_swap(p);
}
static CmpOp unsigned_rel_cmp(CmpOp cop) {
@@ -2822,8 +2822,8 @@ static void parse_mul(Parser* p) {
to_rvalue(p);
parse_unary(p);
to_rvalue(p);
- const Type* lt = cg_top2_type(p->cg);
- const Type* rt = cg_top_type(p->cg);
+ const Type* lt = pcg_top2_type(p);
+ const Type* rt = pcg_top_type(p);
const Type* common = common_fp_type(p, lt, rt);
if (bop == BO_SREM) {
if (!type_is_int(lt) || !type_is_int(rt))
@@ -2836,7 +2836,7 @@ static void parse_mul(Parser* p) {
} else {
const Type* icommon = cint_common_type(p, lt, rt);
coerce_arith_operands(p, icommon);
- cg_binop(p->cg, int_div_rem_binop(bop, icommon));
+ pcg_binop(p, int_div_rem_binop(bop, icommon));
}
}
}
@@ -2845,14 +2845,14 @@ static void scale_pointer_index(Parser* p, u32 elem_size) {
const Type* idx_ty = c_abi_ptrdiff_type(p->abi, p->pool);
coerce_top_to_type(p, idx_ty);
if (elem_size != 1) {
- cg_push_int(p->cg, (i64)elem_size, idx_ty);
- cg_binop(p->cg, BO_IMUL);
+ pcg_push_int(p, (i64)elem_size, idx_ty);
+ pcg_binop(p, BO_IMUL);
}
}
static void emit_add_or_sub(Parser* p, BinOp bop) {
- const Type* lt = cg_top2_type(p->cg);
- const Type* rt = cg_top_type(p->cg);
+ const Type* lt = pcg_top2_type(p);
+ const Type* rt = pcg_top_type(p);
int l_is_ptr = lt && lt->kind == TY_PTR;
int r_is_ptr = rt && rt->kind == TY_PTR;
if (bop == BO_IADD) {
@@ -2864,16 +2864,16 @@ static void emit_add_or_sub(Parser* p, BinOp bop) {
perr(p, "pointer arithmetic on void pointer");
u32 esz = c_abi_sizeof(p->abi, lt->ptr.pointee);
scale_pointer_index(p, esz);
- cg_binop(p->cg, BO_IADD);
+ pcg_binop(p, BO_IADD);
return;
}
if (r_is_ptr && type_is_int(lt)) {
if (rt->ptr.pointee && rt->ptr.pointee->kind == TY_VOID)
perr(p, "pointer arithmetic on void pointer");
- cg_swap(p->cg);
+ pcg_swap(p);
u32 esz = c_abi_sizeof(p->abi, rt->ptr.pointee);
scale_pointer_index(p, esz);
- cg_binop(p->cg, BO_IADD);
+ pcg_binop(p, BO_IADD);
return;
}
} else { /* BO_ISUB */
@@ -2882,7 +2882,7 @@ static void emit_add_or_sub(Parser* p, BinOp bop) {
perr(p, "pointer arithmetic on void pointer");
u32 esz = c_abi_sizeof(p->abi, lt->ptr.pointee);
scale_pointer_index(p, esz);
- cg_binop(p->cg, BO_ISUB);
+ pcg_binop(p, BO_ISUB);
return;
}
if (l_is_ptr && r_is_ptr) {
@@ -2890,12 +2890,12 @@ static void emit_add_or_sub(Parser* p, BinOp bop) {
perr(p, "subtraction of incompatible pointer types");
}
u32 esz = c_abi_sizeof(p->abi, lt->ptr.pointee);
- cg_binop(p->cg, BO_ISUB);
+ pcg_binop(p, BO_ISUB);
if (esz != 1) {
- cg_push_int(p->cg, (i64)esz, ty_size_t(p));
- cg_binop(p->cg, BO_SDIV);
+ pcg_push_int(p, (i64)esz, ty_size_t(p));
+ pcg_binop(p, BO_SDIV);
}
- cg_convert(p->cg, c_abi_ptrdiff_type(p->abi, p->pool));
+ pcg_convert(p, c_abi_ptrdiff_type(p->abi, p->pool));
return;
}
}
@@ -2912,7 +2912,7 @@ static void emit_add_or_sub(Parser* p, BinOp bop) {
}
common = cint_common_type(p, lt, rt);
coerce_arith_operands(p, common);
- cg_binop(p->cg, bop);
+ pcg_binop(p, bop);
}
static void parse_add(Parser* p) {
@@ -2950,25 +2950,25 @@ static void parse_shift(Parser* p) {
advance(p);
to_rvalue(p);
{
- const Type* lt = cg_top_type(p->cg);
+ const Type* lt = pcg_top_type(p);
const Type* lp = cint_promote_type(p, lt);
if (!type_is_int(lt)) perr(p, "shift operator requires integer operands");
- if (cg_top_type(p->cg) != lp) cg_convert(p->cg, lp);
+ if (pcg_top_type(p) != lp) pcg_convert(p, lp);
if (bop == BO_SHR_S && !c_abi_type_info(p->abi, lp).signed_)
bop = BO_SHR_U;
}
parse_add(p);
to_rvalue(p);
{
- const Type* rt = cg_top_type(p->cg);
+ const Type* rt = pcg_top_type(p);
const Type* rp = cint_promote_type(p, rt);
if (!type_is_int(rt)) perr(p, "shift operator requires integer operands");
- if (cg_top_type(p->cg) != rp) cg_convert(p->cg, rp);
+ if (pcg_top_type(p) != rp) pcg_convert(p, rp);
}
- if (!type_is_int(cg_top2_type(p->cg)) || !type_is_int(cg_top_type(p->cg))) {
+ if (!type_is_int(pcg_top2_type(p)) || !type_is_int(pcg_top_type(p))) {
perr(p, "shift operator requires integer operands");
}
- cg_binop(p->cg, bop);
+ pcg_binop(p, bop);
}
}
@@ -2993,8 +2993,8 @@ static void parse_rel(Parser* p) {
parse_shift(p);
to_rvalue(p);
{
- const Type* lt = cg_top2_type(p->cg);
- const Type* rt = cg_top_type(p->cg);
+ const Type* lt = pcg_top2_type(p);
+ const Type* rt = pcg_top_type(p);
const Type* common = common_fp_type(p, lt, rt);
if (lt && lt->kind == TY_PTR && rt && rt->kind == TY_PTR) {
if (!pointer_pointees_compatible(p, lt, rt)) {
@@ -3029,7 +3029,7 @@ static void parse_rel(Parser* p) {
if (!cint_signed(p, common)) cop = unsigned_rel_cmp(cop);
}
}
- cg_cmp(p->cg, cop);
+ pcg_cmp(p, cop);
}
}
@@ -3045,14 +3045,14 @@ static void parse_eq(Parser* p) {
} else {
break;
}
- int lhs_null = null_pointer_constant(p, cg_top_type(p->cg));
+ int lhs_null = null_pointer_constant(p, pcg_top_type(p));
advance(p);
to_rvalue(p);
parse_rel(p);
to_rvalue(p);
{
- const Type* lt = cg_top2_type(p->cg);
- const Type* rt = cg_top_type(p->cg);
+ const Type* lt = pcg_top2_type(p);
+ const Type* rt = pcg_top_type(p);
const Type* common = common_fp_type(p, lt, rt);
int lnull = lhs_null;
int rnull = null_pointer_constant(p, rt);
@@ -3073,7 +3073,7 @@ static void parse_eq(Parser* p) {
coerce_arith_operands(p, common);
}
}
- cg_cmp(p->cg, cop);
+ pcg_cmp(p, cop);
}
}
@@ -3084,12 +3084,12 @@ static void parse_band(Parser* p) {
to_rvalue(p);
parse_eq(p);
to_rvalue(p);
- if (!type_is_int(cg_top2_type(p->cg)) || !type_is_int(cg_top_type(p->cg))) {
+ if (!type_is_int(pcg_top2_type(p)) || !type_is_int(pcg_top_type(p))) {
perr(p, "bitwise operator requires integer operands");
}
coerce_arith_operands(
- p, cint_common_type(p, cg_top2_type(p->cg), cg_top_type(p->cg)));
- cg_binop(p->cg, BO_AND);
+ p, cint_common_type(p, pcg_top2_type(p), pcg_top_type(p)));
+ pcg_binop(p, BO_AND);
}
}
@@ -3100,12 +3100,12 @@ static void parse_bxor(Parser* p) {
to_rvalue(p);
parse_band(p);
to_rvalue(p);
- if (!type_is_int(cg_top2_type(p->cg)) || !type_is_int(cg_top_type(p->cg))) {
+ if (!type_is_int(pcg_top2_type(p)) || !type_is_int(pcg_top_type(p))) {
perr(p, "bitwise operator requires integer operands");
}
coerce_arith_operands(
- p, cint_common_type(p, cg_top2_type(p->cg), cg_top_type(p->cg)));
- cg_binop(p->cg, BO_XOR);
+ p, cint_common_type(p, pcg_top2_type(p), pcg_top_type(p)));
+ pcg_binop(p, BO_XOR);
}
}
@@ -3116,12 +3116,12 @@ static void parse_bor(Parser* p) {
to_rvalue(p);
parse_bxor(p);
to_rvalue(p);
- if (!type_is_int(cg_top2_type(p->cg)) || !type_is_int(cg_top_type(p->cg))) {
+ if (!type_is_int(pcg_top2_type(p)) || !type_is_int(pcg_top_type(p))) {
perr(p, "bitwise operator requires integer operands");
}
coerce_arith_operands(
- p, cint_common_type(p, cg_top2_type(p->cg), cg_top_type(p->cg)));
- cg_binop(p->cg, BO_OR);
+ p, cint_common_type(p, pcg_top2_type(p), pcg_top_type(p)));
+ pcg_binop(p, BO_OR);
}
}
@@ -3141,21 +3141,21 @@ static FrameSlot ll_tmp_slot(Parser* p, const Type* ty) {
fsd.align = c_abi_alignof(p->abi, ty);
fsd.kind = FS_LOCAL;
fsd.flags = FSF_NONE;
- return cg_local(p->cg, &fsd);
+ return pcg_local(p, &fsd);
}
static void ll_store_const(Parser* p, FrameSlot tmp, const Type* ty, i64 v) {
- cg_push_local_typed(p->cg, tmp, ty);
- cg_push_int(p->cg, v, ty);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_local_typed(p, tmp, ty);
+ pcg_push_int(p, v, ty);
+ pcg_store(p);
+ pcg_drop(p);
}
static void parse_land(Parser* p) {
parse_bor(p);
while (is_punct(&p->cur, P_AND)) {
- CGLabel L_false = cg_label_new(p->cg);
- CGLabel L_end = cg_label_new(p->cg);
+ CGLabel L_false = pcg_label_new(p);
+ CGLabel L_end = pcg_label_new(p);
const Type* result_ty = ty_int(p);
FrameSlot tmp = ll_tmp_slot(p, result_ty);
int lhs_known;
@@ -3163,43 +3163,43 @@ static void parse_land(Parser* p) {
int rhs_truth = 0;
advance(p);
to_rvalue(p);
- require_scalar(p, cg_top_type(p->cg), "logical '&&'");
+ require_scalar(p, pcg_top_type(p), "logical '&&'");
lhs_known = cg_top_const_truth(p, &lhs_truth);
if (lhs_known && !lhs_truth) {
- cg_drop(p->cg);
+ pcg_drop(p);
pcg_codegen_suppress_push(p);
parse_bor(p);
to_rvalue(p);
- require_scalar(p, cg_top_type(p->cg), "logical '&&'");
- cg_drop(p->cg);
+ require_scalar(p, pcg_top_type(p), "logical '&&'");
+ pcg_drop(p);
pcg_codegen_suppress_pop(p);
- cg_push_int(p->cg, 0, result_ty);
+ pcg_push_int(p, 0, result_ty);
continue;
}
- cg_branch_false(p->cg, L_false);
+ pcg_branch_false(p, L_false);
parse_bor(p);
to_rvalue(p);
- require_scalar(p, cg_top_type(p->cg), "logical '&&'");
+ require_scalar(p, pcg_top_type(p), "logical '&&'");
if (lhs_known && lhs_truth && cg_top_const_truth(p, &rhs_truth)) {
- cg_drop(p->cg);
- cg_push_int(p->cg, rhs_truth ? 1 : 0, result_ty);
+ pcg_drop(p);
+ pcg_push_int(p, rhs_truth ? 1 : 0, result_ty);
continue;
}
- cg_branch_false(p->cg, L_false);
+ pcg_branch_false(p, L_false);
ll_store_const(p, tmp, result_ty, 1);
- cg_jump(p->cg, L_end);
- cg_label_place(p->cg, L_false);
+ pcg_jump(p, L_end);
+ pcg_label_place(p, L_false);
ll_store_const(p, tmp, result_ty, 0);
- cg_label_place(p->cg, L_end);
- cg_push_local_typed(p->cg, tmp, result_ty);
+ pcg_label_place(p, L_end);
+ pcg_push_local_typed(p, tmp, result_ty);
}
}
static void parse_lor(Parser* p) {
parse_land(p);
while (is_punct(&p->cur, P_OR)) {
- CGLabel L_true = cg_label_new(p->cg);
- CGLabel L_end = cg_label_new(p->cg);
+ CGLabel L_true = pcg_label_new(p);
+ CGLabel L_end = pcg_label_new(p);
const Type* result_ty = ty_int(p);
FrameSlot tmp = ll_tmp_slot(p, result_ty);
int lhs_known;
@@ -3207,35 +3207,35 @@ static void parse_lor(Parser* p) {
int rhs_truth = 0;
advance(p);
to_rvalue(p);
- require_scalar(p, cg_top_type(p->cg), "logical '||'");
+ require_scalar(p, pcg_top_type(p), "logical '||'");
lhs_known = cg_top_const_truth(p, &lhs_truth);
if (lhs_known && lhs_truth) {
- cg_drop(p->cg);
+ pcg_drop(p);
pcg_codegen_suppress_push(p);
parse_land(p);
to_rvalue(p);
- require_scalar(p, cg_top_type(p->cg), "logical '||'");
- cg_drop(p->cg);
+ require_scalar(p, pcg_top_type(p), "logical '||'");
+ pcg_drop(p);
pcg_codegen_suppress_pop(p);
- cg_push_int(p->cg, 1, result_ty);
+ pcg_push_int(p, 1, result_ty);
continue;
}
- cg_branch_true(p->cg, L_true);
+ pcg_branch_true(p, L_true);
parse_land(p);
to_rvalue(p);
- require_scalar(p, cg_top_type(p->cg), "logical '||'");
+ require_scalar(p, pcg_top_type(p), "logical '||'");
if (lhs_known && !lhs_truth && cg_top_const_truth(p, &rhs_truth)) {
- cg_drop(p->cg);
- cg_push_int(p->cg, rhs_truth ? 1 : 0, result_ty);
+ pcg_drop(p);
+ pcg_push_int(p, rhs_truth ? 1 : 0, result_ty);
continue;
}
- cg_branch_true(p->cg, L_true);
+ pcg_branch_true(p, L_true);
ll_store_const(p, tmp, result_ty, 0);
- cg_jump(p->cg, L_end);
- cg_label_place(p->cg, L_true);
+ pcg_jump(p, L_end);
+ pcg_label_place(p, L_true);
ll_store_const(p, tmp, result_ty, 1);
- cg_label_place(p->cg, L_end);
- cg_push_local_typed(p->cg, tmp, result_ty);
+ pcg_label_place(p, L_end);
+ pcg_push_local_typed(p, tmp, result_ty);
}
}
@@ -3244,8 +3244,8 @@ static const Type* common_fp_type(Parser* p, const Type* a, const Type* b);
static void parse_ternary(Parser* p) {
parse_lor(p);
if (!is_punct(&p->cur, '?')) return;
- CGLabel L_else = cg_label_new(p->cg);
- CGLabel L_end = cg_label_new(p->cg);
+ CGLabel L_else = pcg_label_new(p);
+ CGLabel L_end = pcg_label_new(p);
const Type* result_ty = ty_int(p);
int then_null = 0;
FrameSlot tmp;
@@ -3253,16 +3253,16 @@ static void parse_ternary(Parser* p) {
const Type* then_store_ty;
advance(p); /* '?' */
to_rvalue(p);
- require_scalar(p, cg_top_type(p->cg), "conditional operator");
- cg_branch_false(p->cg, L_else);
+ require_scalar(p, pcg_top_type(p), "conditional operator");
+ pcg_branch_false(p, L_else);
parse_expr(p);
to_rvalue(p);
- result_ty = cg_top_type(p->cg);
+ result_ty = pcg_top_type(p);
then_null = null_pointer_constant(p, result_ty);
if (!result_ty) result_ty = ty_int(p);
if (type_is_int(result_ty)) {
result_ty = type_promoted(p->pool, result_ty);
- if (cg_top_type(p->cg) != result_ty) cg_convert(p->cg, result_ty);
+ if (pcg_top_type(p) != result_ty) pcg_convert(p, result_ty);
}
then_store_ty =
then_null ? type_ptr(p->pool, type_prim(p->pool, TY_VOID)) : result_ty;
@@ -3272,18 +3272,18 @@ static void parse_ternary(Parser* p) {
fsd.align = c_abi_alignof(p->abi, then_store_ty);
fsd.kind = FS_LOCAL;
fsd.flags = FSF_NONE;
- tmp = cg_local(p->cg, &fsd);
- if (cg_top_type(p->cg) != then_store_ty) cg_convert(p->cg, then_store_ty);
- cg_push_local_typed(p->cg, tmp, then_store_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
- cg_jump(p->cg, L_end);
- cg_label_place(p->cg, L_else);
+ tmp = pcg_local(p, &fsd);
+ if (pcg_top_type(p) != then_store_ty) pcg_convert(p, then_store_ty);
+ pcg_push_local_typed(p, tmp, then_store_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
+ pcg_jump(p, L_end);
+ pcg_label_place(p, L_else);
expect_punct(p, ':', "':' in ternary");
parse_assign_expr(p);
to_rvalue(p);
- const Type* else_ty = cg_top_type(p->cg);
+ const Type* else_ty = pcg_top_type(p);
const Type* common = common_fp_type(p, result_ty, else_ty);
const Type* ptr_result = conditional_pointer_type(
p, result_ty, then_null, else_ty, null_pointer_constant(p, else_ty));
@@ -3297,14 +3297,14 @@ static void parse_ternary(Parser* p) {
} else if (!type_compatible(result_ty, else_ty)) {
perr(p, "conditional operator type mismatch");
}
- if (cg_top_type(p->cg) != result_ty) {
- cg_convert(p->cg, result_ty);
+ if (pcg_top_type(p) != result_ty) {
+ pcg_convert(p, result_ty);
}
- cg_push_local_typed(p->cg, tmp, result_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
- cg_label_place(p->cg, L_end);
+ pcg_push_local_typed(p, tmp, result_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
+ pcg_label_place(p, L_end);
if (common && common != result_ty) {
FrameSlotDesc cfsd;
FrameSlot ctmp;
@@ -3314,18 +3314,18 @@ static void parse_ternary(Parser* p) {
cfsd.align = c_abi_alignof(p->abi, common);
cfsd.kind = FS_LOCAL;
cfsd.flags = FSF_NONE;
- ctmp = cg_local(p->cg, &cfsd);
- cg_push_local_typed(p->cg, tmp, result_ty);
- cg_load(p->cg);
- cg_convert(p->cg, common);
- cg_push_local_typed(p->cg, ctmp, common);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
- cg_push_local_typed(p->cg, ctmp, common);
+ ctmp = pcg_local(p, &cfsd);
+ pcg_push_local_typed(p, tmp, result_ty);
+ pcg_load(p);
+ pcg_convert(p, common);
+ pcg_push_local_typed(p, ctmp, common);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
+ pcg_push_local_typed(p, ctmp, common);
return;
}
- cg_push_local_typed(p->cg, tmp, result_ty);
+ pcg_push_local_typed(p, tmp, result_ty);
}
void parse_assign_expr(Parser* p) {
@@ -3373,7 +3373,7 @@ void parse_assign_expr(Parser* p) {
perr(p, "assignment requires modifiable lvalue");
}
advance(p);
- const Type* lhs = cg_top_type(p->cg);
+ const Type* lhs = pcg_top_type(p);
if (compound == BO_SHR_S && !c_abi_type_info(p->abi, lhs).signed_)
compound = BO_SHR_U;
{
@@ -3398,14 +3398,14 @@ void parse_assign_expr(Parser* p) {
parse_assign_expr(p);
to_rvalue(p);
{
- const Type* rhs = cg_top_type(p->cg);
+ const Type* rhs = pcg_top_type(p);
CSemCheck chk =
c_sem_check_assignment(p->pool, lhs, rhs, C_SEM_ASSIGN_EXPR);
if (!chk.ok)
perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message)));
}
coerce_top_to_lvalue(p);
- cg_store(p->cg);
+ pcg_store(p);
return;
}
{
@@ -3418,11 +3418,11 @@ void parse_assign_expr(Parser* p) {
}
pcg_dup_type(p);
}
- cg_load(p->cg);
+ pcg_load(p);
parse_assign_expr(p);
to_rvalue(p);
{
- const Type* rhs = cg_top_type(p->cg);
+ const Type* rhs = pcg_top_type(p);
int op = '+';
switch (compound) {
case BO_IADD:
@@ -3469,8 +3469,8 @@ void parse_assign_expr(Parser* p) {
if (compound == BO_IADD || compound == BO_ISUB) {
emit_add_or_sub(p, compound);
} else {
- const Type* lt = cg_top2_type(p->cg);
- const Type* rt = cg_top_type(p->cg);
+ const Type* lt = pcg_top2_type(p);
+ const Type* rt = pcg_top_type(p);
const Type* common = common_fp_type(p, lt, rt);
if (common) {
if (compound == BO_SREM)
@@ -3479,19 +3479,19 @@ void parse_assign_expr(Parser* p) {
} else {
const Type* icommon = cint_common_type(p, lt, rt);
coerce_arith_operands(p, icommon);
- cg_binop(p->cg, int_div_rem_binop(compound, icommon));
+ pcg_binop(p, int_div_rem_binop(compound, icommon));
}
}
coerce_top_to_type(p, lhs);
if (p->cg_type_sp >= 2) p->cg_type_stack[p->cg_type_sp - 2u] = lhs;
- cg_store(p->cg);
+ pcg_store(p);
}
void parse_expr(Parser* p) {
parse_assign_expr(p);
while (is_punct(&p->cur, ',')) {
advance(p);
- cg_drop(p->cg);
+ pcg_drop(p);
parse_assign_expr(p);
}
}
diff --git a/lang/c/parse/parse_init.c b/lang/c/parse/parse_init.c
@@ -146,7 +146,7 @@ static int try_init_aggregate_from_expr(Parser* p, FrameSlot slot,
save_sp = p->cg_type_sp;
pcg_codegen_suppress_push(p);
parse_assign_expr(p);
- expr_ty = cg_top_type(p->cg);
+ expr_ty = pcg_top_type(p);
compatible =
type_compatible(type_unqual(p->pool, ty), type_unqual(p->pool, expr_ty));
p->cg_type_sp = save_sp;
@@ -157,7 +157,7 @@ static int try_init_aggregate_from_expr(Parser* p, FrameSlot slot,
parse_assign_expr(p);
if (!type_compatible(type_unqual(p->pool, ty),
- type_unqual(p->pool, cg_top_type(p->cg)))) {
+ type_unqual(p->pool, pcg_top_type(p)))) {
perr(p, "incompatible aggregate initializer");
}
emit_struct_copy_into_slot(p, slot, arr_ty, offset, ty);
@@ -168,7 +168,7 @@ static int try_init_aggregate_from_expr(Parser* p, FrameSlot slot,
* local `slot` (whose type is `arr_ty`), with element type `elem_ty`. */
void push_subobject_lv(Parser* p, FrameSlot slot, const Type* arr_ty,
u32 offset, const Type* elem_ty) {
- cg_push_local_typed(p->cg, slot, arr_ty);
+ pcg_push_local_typed(p, slot, arr_ty);
/* Fold the byte offset onto the local lvalue's aux; the next
* load/store/addr will bake it into the memop's ea.offset. The result is an
* lvalue of elem_ty backed by the frame slot. */
@@ -210,16 +210,16 @@ static void emit_copy_leaf(Parser* p, FrameSlot dst_slot,
FrameSlot src_ptr_slot, const Type* src_ptr_ty,
u32 src_off, const Type* leaf_ty) {
push_subobject_lv(p, dst_slot, dst_arr_ty, dst_off, leaf_ty);
- cg_push_local_typed(p->cg, src_ptr_slot, src_ptr_ty);
- cg_load(p->cg);
+ pcg_push_local_typed(p, src_ptr_slot, src_ptr_ty);
+ pcg_load(p);
/* TOS is now a pointer rvalue (the loaded source pointer). Retag as a
* C-language lvalue with POINTER_RV base, then fold the source byte offset
- * onto its aux. The next cg_load consumes the EA into the memop. */
+ * onto its aux. The next pcg_load consumes the EA into the memop. */
pcg_deref(p, leaf_ty);
pcg_lv_member(p, (i64)src_off, leaf_ty, 0, 0, 0);
- cg_load(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_load(p);
+ pcg_store(p);
+ pcg_drop(p);
}
/* Walk a (possibly nested) aggregate, emitting a leaf load+store for each
@@ -270,18 +270,18 @@ void emit_struct_copy_into_slot(Parser* p, FrameSlot dst_slot,
const Type* ptr_ty = type_ptr(p->pool, ty);
FrameSlotDesc fsd;
FrameSlot src_ptr_slot;
- cg_addr(p->cg);
+ pcg_addr(p);
memset(&fsd, 0, sizeof fsd);
fsd.type = ptr_ty;
fsd.size = c_abi_sizeof(p->abi, ptr_ty);
fsd.align = c_abi_alignof(p->abi, ptr_ty);
fsd.kind = FS_LOCAL;
fsd.flags = FSF_NONE;
- src_ptr_slot = cg_local(p->cg, &fsd);
- cg_push_local_typed(p->cg, src_ptr_slot, ptr_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ src_ptr_slot = pcg_local(p, &fsd);
+ pcg_push_local_typed(p, src_ptr_slot, ptr_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
emit_walk_copy(p, dst_slot, dst_arr_ty, dst_off, src_ptr_slot, ptr_ty, 0, ty);
}
@@ -302,9 +302,9 @@ static void zero_init_at(Parser* p, FrameSlot slot, const Type* arr_ty,
if (f->flags & FIELD_ZERO_WIDTH) continue;
if (f->flags & FIELD_BITFIELD) {
push_record_field_lv(p, slot, arr_ty, offset, ty, i);
- cg_push_int(p->cg, 0, f->type);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_int(p, 0, f->type);
+ pcg_store(p);
+ pcg_drop(p);
continue;
}
{
@@ -325,9 +325,9 @@ static void zero_init_at(Parser* p, FrameSlot slot, const Type* arr_ty,
return;
}
push_subobject_lv(p, slot, arr_ty, offset, ty);
- cg_push_int(p->cg, 0, ty);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_int(p, 0, ty);
+ pcg_store(p);
+ pcg_drop(p);
}
static void init_field_at(Parser* p, FrameSlot slot, const Type* arr_ty,
@@ -340,15 +340,15 @@ static void init_field_at(Parser* p, FrameSlot slot, const Type* arr_ty,
parse_assign_expr(p);
to_rvalue(p);
{
- const Type* rhs = cg_top_type(p->cg);
+ const Type* rhs = pcg_top_type(p);
CSemCheck chk =
c_sem_check_assignment(p->pool, f->type, rhs, C_SEM_ASSIGN_INIT);
if (!chk.ok)
perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message)));
}
coerce_top_to_lvalue(p);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_store(p);
+ pcg_drop(p);
return;
}
init_at(p, slot, arr_ty, rec_offset + L->fields[field_index].offset, f->type);
@@ -367,17 +367,17 @@ static void init_string_at(Parser* p, FrameSlot slot, const Type* arr_ty,
if (copy > count) copy = count;
for (i = 0; i < copy; ++i) {
push_subobject_lv(p, slot, arr_ty, offset + (u32)i * elem_size, elem_ty);
- cg_push_int(p->cg,
+ pcg_push_int(p,
(i64)decode_lit_unit_le(bytes + i * elem_size, elem_size),
elem_ty);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_store(p);
+ pcg_drop(p);
}
for (; i < count; ++i) {
push_subobject_lv(p, slot, arr_ty, offset + (u32)i * elem_size, elem_ty);
- cg_push_int(p->cg, 0, elem_ty);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_int(p, 0, elem_ty);
+ pcg_store(p);
+ pcg_drop(p);
}
cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap,
bytes, 0);
@@ -534,9 +534,9 @@ static u32 init_struct_fields(Parser* p, FrameSlot slot, const Type* arr_ty,
if (zf->flags & FIELD_BITFIELD) {
if (!(zf->flags & FIELD_ZERO_WIDTH)) {
push_record_field_lv(p, slot, arr_ty, offset, ty, zero_lo);
- cg_push_int(p->cg, 0, zf->type);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_int(p, 0, zf->type);
+ pcg_store(p);
+ pcg_drop(p);
}
} else {
u32 zoff = offset + L->fields[zero_lo].offset;
@@ -588,9 +588,9 @@ static u32 init_struct_fields(Parser* p, FrameSlot slot, const Type* arr_ty,
if (f->flags & FIELD_BITFIELD) {
if (!(f->flags & FIELD_ZERO_WIDTH)) {
push_record_field_lv(p, slot, arr_ty, offset, ty, j);
- cg_push_int(p->cg, 0, f->type);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_int(p, 0, f->type);
+ pcg_store(p);
+ pcg_drop(p);
}
} else {
u32 foff = offset + L->fields[j].offset;
@@ -632,9 +632,9 @@ static void init_aggregate_remainder(Parser* p, FrameSlot slot,
if (f->flags & FIELD_BITFIELD) {
if (!(f->flags & FIELD_ZERO_WIDTH)) {
push_record_field_lv(p, slot, arr_ty, offset, ty, i);
- cg_push_int(p->cg, 0, f->type);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_int(p, 0, f->type);
+ pcg_store(p);
+ pcg_drop(p);
}
} else {
const Type* fty = init_field_type_at(ty, i);
@@ -765,14 +765,14 @@ void init_at(Parser* p, FrameSlot slot, const Type* arr_ty, u32 offset,
parse_assign_expr(p);
to_rvalue(p);
{
- const Type* rhs = cg_top_type(p->cg);
+ const Type* rhs = pcg_top_type(p);
CSemCheck chk = c_sem_check_assignment(p->pool, ty, rhs, C_SEM_ASSIGN_INIT);
if (!chk.ok)
perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message)));
}
coerce_top_to_lvalue(p);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_store(p);
+ pcg_drop(p);
if (had_brace) {
accept_punct(p, ',');
expect_punct(p, '}', "'}' after scalar initializer");
diff --git a/lang/c/parse/parse_stmt.c b/lang/c/parse/parse_stmt.c
@@ -40,13 +40,13 @@ static void parse_if_stmt(Parser* p) {
expect_punct(p, '(', "'('");
parse_expr(p);
to_rvalue(p);
- if (!c_type_is_scalar(cg_top_type(p->cg))) {
+ if (!c_type_is_scalar(pcg_top_type(p))) {
perr(p, "if condition requires scalar type");
}
cond_known = cfree_cg_top_const_int(p->cg, &cond);
expect_punct(p, ')', "')'");
if (cond_known) {
- cg_drop(p->cg);
+ pcg_drop(p);
if (cond) {
parse_stmt(p);
if (accept_kw_stmt(p, KW_ELSE)) parse_stmt_suppressed(p);
@@ -78,7 +78,7 @@ static void parse_while_stmt(Parser* p) {
/* Drive the structured-CF API so the C-source target can lower this to
* `for (;;) { … break; … continue; }` instead of goto soup. The labels
* the scope mints are reused as cur_break/cur_continue, so parse_break
- * /parse_continue/etc. keep using their existing raw `cg_jump` calls —
+ * /parse_continue/etc. keep using their existing raw `pcg_jump` calls —
* the C target recognizes the labels as the innermost scope's
* boundaries and emits the structured keywords on its own. */
CfreeCgScope scope = cfree_cg_scope_begin(p->cg, CFREE_CG_TYPE_NONE);
@@ -89,24 +89,24 @@ static void parse_while_stmt(Parser* p) {
expect_punct(p, '(', "'('");
parse_expr(p);
to_rvalue(p);
- if (!c_type_is_scalar(cg_top_type(p->cg))) {
+ if (!c_type_is_scalar(pcg_top_type(p))) {
perr(p, "while condition requires scalar type");
}
expect_punct(p, ')', "')'");
- cg_branch_false(p->cg, L_end);
+ pcg_branch_false(p, L_end);
p->cur_break = L_end;
p->cur_continue = L_top;
parse_stmt(p);
p->cur_break = saved_break;
p->cur_continue = saved_continue;
- cg_jump(p->cg, L_top);
+ pcg_jump(p, L_top);
cfree_cg_scope_end(p->cg, scope);
}
static void parse_for_stmt(Parser* p) {
- CGLabel L_top = cg_label_new(p->cg);
- CGLabel L_step = cg_label_new(p->cg);
- CGLabel L_end = cg_label_new(p->cg);
+ CGLabel L_top = pcg_label_new(p);
+ CGLabel L_step = pcg_label_new(p);
+ CGLabel L_end = pcg_label_new(p);
CGLabel saved_break = p->cur_break;
CGLabel saved_continue = p->cur_continue;
@@ -120,33 +120,33 @@ static void parse_for_stmt(Parser* p) {
parse_local_decl(p, &specs);
} else {
parse_expr(p);
- cg_drop(p->cg);
+ pcg_drop(p);
expect_punct(p, ';', "';'");
}
}
- cg_label_place(p->cg, L_top);
+ pcg_label_place(p, L_top);
if (!is_punct(&p->cur, ';')) {
parse_expr(p);
to_rvalue(p);
- if (!c_type_is_scalar(cg_top_type(p->cg))) {
+ if (!c_type_is_scalar(pcg_top_type(p))) {
perr(p, "for condition requires scalar type");
}
- cg_branch_false(p->cg, L_end);
+ pcg_branch_false(p, L_end);
}
expect_punct(p, ';', "';'");
{
- CGLabel L_body = cg_label_new(p->cg);
- cg_jump(p->cg, L_body);
- cg_label_place(p->cg, L_step);
+ CGLabel L_body = pcg_label_new(p);
+ pcg_jump(p, L_body);
+ pcg_label_place(p, L_step);
if (!is_punct(&p->cur, ')')) {
parse_expr(p);
- cg_drop(p->cg);
+ pcg_drop(p);
}
- cg_jump(p->cg, L_top);
+ pcg_jump(p, L_top);
expect_punct(p, ')', "')'");
- cg_label_place(p->cg, L_body);
+ pcg_label_place(p, L_body);
p->cur_break = L_end;
p->cur_continue = L_step;
@@ -154,8 +154,8 @@ static void parse_for_stmt(Parser* p) {
p->cur_break = saved_break;
p->cur_continue = saved_continue;
- cg_jump(p->cg, L_step);
- cg_label_place(p->cg, L_end);
+ pcg_jump(p, L_step);
+ pcg_label_place(p, L_end);
}
scope_pop(p);
}
@@ -165,7 +165,7 @@ static void parse_return_stmt(Parser* p) {
if (p->cur_func_ret && p->cur_func_ret->kind != TY_VOID) {
perr(p, "return with no value in non-void function");
}
- cg_ret(p->cg, 0);
+ pcg_ret(p, 0);
return;
}
if (p->cur_func_ret && p->cur_func_ret->kind == TY_VOID) {
@@ -174,7 +174,7 @@ static void parse_return_stmt(Parser* p) {
parse_expr(p);
to_rvalue(p);
{
- const Type* rhs = cg_top_type(p->cg);
+ const Type* rhs = pcg_top_type(p);
CSemCheck chk = c_sem_check_assignment(p->pool, p->cur_func_ret, rhs,
C_SEM_ASSIGN_RETURN);
if (!chk.ok)
@@ -182,51 +182,51 @@ static void parse_return_stmt(Parser* p) {
}
/* Convert the value to the function return type, as `return` performs the
* equivalent of assignment to an object of the return type (§6.8.6.4).
- * cg_ret expects the value already in the return type; without this a
+ * pcg_ret expects the value already in the return type; without this a
* narrower value (e.g. a _Bool call result returned from an int function)
* would be reloaded at the wider return width and read adjacent bytes. */
coerce_top_to_type(p, p->cur_func_ret);
expect_punct(p, ';', "';' after return value");
- cg_ret(p->cg, 1);
+ pcg_ret(p, 1);
}
static void parse_break_stmt(Parser* p) {
if (p->cur_break == 0) perr(p, "'break' outside of loop or switch");
- cg_jump(p->cg, p->cur_break);
+ pcg_jump(p, p->cur_break);
expect_punct(p, ';', "';' after break");
}
static void parse_continue_stmt(Parser* p) {
if (p->cur_continue == 0) perr(p, "'continue' outside of loop");
- cg_jump(p->cg, p->cur_continue);
+ pcg_jump(p, p->cur_continue);
expect_punct(p, ';', "';' after continue");
}
static void parse_do_stmt(Parser* p) {
- CGLabel L_top = cg_label_new(p->cg);
- CGLabel L_cond = cg_label_new(p->cg);
- CGLabel L_end = cg_label_new(p->cg);
+ CGLabel L_top = pcg_label_new(p);
+ CGLabel L_cond = pcg_label_new(p);
+ CGLabel L_end = pcg_label_new(p);
CGLabel saved_break = p->cur_break;
CGLabel saved_continue = p->cur_continue;
- cg_label_place(p->cg, L_top);
+ pcg_label_place(p, L_top);
p->cur_break = L_end;
p->cur_continue = L_cond;
parse_stmt(p);
p->cur_break = saved_break;
p->cur_continue = saved_continue;
- cg_label_place(p->cg, L_cond);
+ pcg_label_place(p, L_cond);
if (!is_kw(p, &p->cur, KW_WHILE)) perr(p, "expected 'while' after do-body");
advance(p); /* while */
expect_punct(p, '(', "'('");
parse_expr(p);
to_rvalue(p);
- if (!c_type_is_scalar(cg_top_type(p->cg))) {
+ if (!c_type_is_scalar(pcg_top_type(p))) {
perr(p, "do-while condition requires scalar type");
}
expect_punct(p, ')', "')' after do-while condition");
expect_punct(p, ';', "';' after do-while");
- cg_branch_true(p->cg, L_top);
- cg_label_place(p->cg, L_end);
+ pcg_branch_true(p, L_top);
+ pcg_label_place(p, L_end);
}
GotoLabel* label_get_or_create(Parser* p, Sym name, SrcLoc loc) {
@@ -238,7 +238,7 @@ GotoLabel* label_get_or_create(Parser* p, Sym name, SrcLoc loc) {
if (!gl) perr(p, "out of memory in label_get_or_create");
memset(gl, 0, sizeof *gl);
gl->name = name;
- gl->label = cg_label_new(p->cg);
+ gl->label = pcg_label_new(p);
gl->placed = 0;
gl->first_use = loc;
gl->min_forward_vla_mark = p->vla_mark;
@@ -273,7 +273,7 @@ static void parse_computed_goto(Parser* p) {
advance(p); /* '*' */
parse_expr(p);
to_rvalue(p);
- if (!type_is_ptr(cg_top_type(p->cg))) {
+ if (!type_is_ptr(pcg_top_type(p))) {
perr(p, "computed goto requires a pointer operand");
}
expect_punct(p, ';', "';' after computed goto");
@@ -317,7 +317,7 @@ static void parse_goto_stmt(Parser* p) {
} else if (p->vla_mark < gl->min_forward_vla_mark) {
gl->min_forward_vla_mark = p->vla_mark;
}
- cg_jump(p->cg, gl->label);
+ pcg_jump(p, gl->label);
}
static void parse_label_stmt(Parser* p) {
@@ -333,7 +333,7 @@ static void parse_label_stmt(Parser* p) {
}
gl->placed = 1;
gl->label_vla_mark = p->vla_mark;
- cg_label_place(p->cg, gl->label);
+ pcg_label_place(p, gl->label);
parse_stmt(p);
}
@@ -348,8 +348,8 @@ static void parse_case_stmt(Parser* p) {
if (ce->value == v) perr(p, "duplicate case value");
}
expect_punct(p, ':', "':' after case constant");
- L = cg_label_new(p->cg);
- cg_label_place(p->cg, L);
+ L = pcg_label_new(p);
+ pcg_label_place(p, L);
ce = arena_new(p->pool->arena, CaseEntry);
if (!ce) perr(p, "out of memory in parse_case_stmt");
ce->value = v;
@@ -364,8 +364,8 @@ static void parse_default_stmt(Parser* p) {
if (!p->cur_switch) perr(p, "'default' label not in switch statement");
expect_punct(p, ':', "':' after default");
if (p->cur_switch->default_label != 0) perr(p, "duplicate 'default' label");
- L = cg_label_new(p->cg);
- cg_label_place(p->cg, L);
+ L = pcg_label_new(p);
+ pcg_label_place(p, L);
p->cur_switch->default_label = L;
parse_stmt(p);
}
@@ -380,7 +380,7 @@ static void parse_switch_stmt(Parser* p) {
* emit a real `switch (sel) { case V: goto L_V; …; default: goto
* L_def; }`. */
CfreeCgScope scope = cfree_cg_scope_begin(p->cg, CFREE_CG_TYPE_NONE);
- CGLabel L_dispatch = cg_label_new(p->cg);
+ CGLabel L_dispatch = pcg_label_new(p);
CGLabel L_end = cfree_cg_scope_break_label(p->cg, scope);
CGLabel saved_break = p->cur_break;
SwitchCtx ctx;
@@ -394,7 +394,7 @@ static void parse_switch_stmt(Parser* p) {
expect_punct(p, '(', "'('");
parse_expr(p);
to_rvalue(p);
- vty = cg_top_type(p->cg);
+ vty = pcg_top_type(p);
if (!vty) vty = type_prim(p->pool, TY_INT);
if (!type_is_int(vty)) perr(p, "switch expression requires integer type");
/* C99 6.8.4.2: the integer promotions are performed on the controlling
@@ -408,7 +408,7 @@ static void parse_switch_stmt(Parser* p) {
else
prom = type_promoted(p->pool, prom);
if (prom && prom != vty) {
- cg_convert(p->cg, prom);
+ pcg_convert(p, prom);
vty = prom;
}
}
@@ -420,16 +420,16 @@ static void parse_switch_stmt(Parser* p) {
fsd.size = c_abi_sizeof(p->abi, vty);
fsd.align = c_abi_alignof(p->abi, vty);
fsd.kind = FS_LOCAL;
- ctx.value_slot = cg_local(p->cg, &fsd);
+ ctx.value_slot = pcg_local(p, &fsd);
ctx.value_type = vty;
ctx.parent = saved_switch;
- cg_push_local_typed(p->cg, ctx.value_slot, vty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_local_typed(p, ctx.value_slot, vty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
- cg_jump(p->cg, L_dispatch);
+ pcg_jump(p, L_dispatch);
p->cur_switch = &ctx;
p->cur_break = L_end;
@@ -437,9 +437,9 @@ static void parse_switch_stmt(Parser* p) {
p->cur_break = saved_break;
p->cur_switch = saved_switch;
- cg_jump(p->cg, L_end);
+ pcg_jump(p, L_end);
- cg_label_place(p->cg, L_dispatch);
+ pcg_label_place(p, L_dispatch);
/* Reverse cases into source order; CaseEntry list grows at the head
* during parsing so iteration here is LIFO without the flip. */
prev = NULL;
@@ -470,8 +470,8 @@ static void parse_switch_stmt(Parser* p) {
i++;
}
}
- cg_push_local_typed(p->cg, ctx.value_slot, vty);
- cg_load(p->cg);
+ pcg_push_local_typed(p, ctx.value_slot, vty);
+ pcg_load(p);
{
CfreeCgSwitch sw;
memset(&sw, 0, sizeof sw);
@@ -604,22 +604,22 @@ static void parse_asm_stmt(Parser* p) {
c.dir = ASM_OUT;
expect_punct(p, '(', "'(' before asm output lvalue");
parse_assign_expr(p);
- val_ty = cg_top_type(p->cg);
+ val_ty = pcg_top_type(p);
if (!val_ty) perr(p, "asm output: cannot determine lvalue type");
c.type = val_ty;
- cg_addr(p->cg);
- ptr_ty = cg_top_type(p->cg);
+ pcg_addr(p);
+ ptr_ty = pcg_top_type(p);
if (!ptr_ty) perr(p, "asm output: cannot take address");
memset(&fsd, 0, sizeof fsd);
fsd.type = ptr_ty;
fsd.size = 8;
fsd.align = 8;
fsd.kind = FS_LOCAL;
- slot = cg_local(p->cg, &fsd);
- cg_push_local_typed(p->cg, slot, ptr_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ slot = pcg_local(p, &fsd);
+ pcg_push_local_typed(p, slot, ptr_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
lv.addr_slot = slot;
lv.ptr_ty = ptr_ty;
lv.val_ty = val_ty;
@@ -657,7 +657,7 @@ static void parse_asm_stmt(Parser* p) {
expect_punct(p, '(', "'(' before asm input expression");
parse_assign_expr(p);
to_rvalue(p);
- c.type = cg_top_type(p->cg);
+ c.type = pcg_top_type(p);
expect_punct(p, ')', "')' after asm input expression");
if (nin == cap_in) {
u32 nc = cap_in * 2;
@@ -738,10 +738,10 @@ static void parse_asm_stmt(Parser* p) {
"matching-digit syntax");
}
AsmOutLValue* lv = &out_lvs[i];
- cg_push_local_typed(p->cg, lv->addr_slot, lv->ptr_ty);
- cg_load(p->cg);
- cg_deref(p->cg, lv->val_ty);
- cg_load(p->cg);
+ pcg_push_local_typed(p, lv->addr_slot, lv->ptr_ty);
+ pcg_load(p);
+ pcg_deref(p, lv->val_ty);
+ pcg_load(p);
AsmConstraint mc;
memset(&mc, 0, sizeof mc);
mc.str = k_match_strs[i];
@@ -751,19 +751,19 @@ static void parse_asm_stmt(Parser* p) {
}
}
- cg_set_loc(p->cg, loc);
- cg_inline_asm(p->cg, tmpl, outs, nout, ins, nin, clobbers, nclob);
+ pcg_set_loc(p, loc);
+ pcg_inline_asm(p, tmpl, outs, nout, ins, nin, clobbers, nclob);
if (nout > 0) {
u32 i;
for (i = nout; i-- > 0;) {
AsmOutLValue* lv = &out_lvs[i];
- cg_push_local_typed(p->cg, lv->addr_slot, lv->ptr_ty);
- cg_load(p->cg);
- cg_deref(p->cg, lv->val_ty);
- cg_swap(p->cg);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_push_local_typed(p, lv->addr_slot, lv->ptr_ty);
+ pcg_load(p);
+ pcg_deref(p, lv->val_ty);
+ pcg_swap(p);
+ pcg_store(p);
+ pcg_drop(p);
}
}
}
@@ -796,7 +796,7 @@ void parse_compound_stmt(Parser* p) {
}
void parse_stmt(Parser* p) {
- cg_set_loc(p->cg, tok_loc_stmt(&p->cur));
+ pcg_set_loc(p, tok_loc_stmt(&p->cur));
if (p->cur.kind == TOK_IDENT && ident_kw_stmt(p, p->cur.v.ident) == KW_NONE) {
Tok n = peek1(p);
if (is_punct(&n, ':')) {
@@ -874,6 +874,6 @@ void parse_stmt(Parser* p) {
}
/* Expression statement. */
parse_expr(p);
- cg_drop(p->cg);
+ pcg_drop(p);
expect_punct(p, ';', "';' after expression");
}
diff --git a/lang/c/parse/parse_type.c b/lang/c/parse/parse_type.c
@@ -1388,14 +1388,14 @@ int parse_decl_suffix(Parser* p, DeclSuffix* out) {
fsd.size = c_abi_sizeof(p->abi, fsd.type);
fsd.align = c_abi_alignof(p->abi, fsd.type);
fsd.kind = FS_LOCAL;
- out->vla_count_slot = cg_local(p->cg, &fsd);
+ out->vla_count_slot = pcg_local(p, &fsd);
parse_assign_expr(p);
to_rvalue(p);
- cg_push_local_typed(p->cg, out->vla_count_slot, fsd.type);
- cg_swap(p->cg);
+ pcg_push_local_typed(p, out->vla_count_slot, fsd.type);
+ pcg_swap(p);
coerce_top_to_lvalue(p);
- cg_store(p->cg);
- cg_drop(p->cg);
+ pcg_store(p);
+ pcg_drop(p);
p->vla_pending = 1;
++p->vla_mark;
p->vla_pending_count_slot = out->vla_count_slot;