+/*
+ * TODO: On return, we can use a more efficient
+ * untagging (we know the constructor tag).
+ *
+ * When entering stg_sel_#_upd, we know R1 points to its closure,
+ * so it's untagged.
+ * The payload might be a thunk or a constructor,
+ * so we enter it.
+ *
+ * When returning, we know for sure it is a constructor,
+ * so we untag it before accessing the field.
+ *
+ */
+#ifdef PROFILING
+// When profiling, we cannot shortcut by checking the tag,
+// because LDV profiling relies on entering closures to mark them as
+// "used".
+#define SEL_ENTER(offset) \
+ R1 = UNTAG(R1); \
+ jump %GET_ENTRY(R1);
+#else
+#define SEL_ENTER(offset) \
+ if (GETTAG(R1) != 0) { \
+ jump RET_LBL(stg_sel_ret_##offset##_upd); \
+ } \
+ jump %GET_ENTRY(R1);
+#endif
+
+#define SELECTOR_CODE_UPD(offset) \