+#ifdef __x86_64__
+
+#define PTR_SCALE 3
+#define NA_TMP_REG xAX // non-arg tmp from reg_temp[]
+
+#define EMIT_REX_IF(w, r, rm) do { \
+ int r_ = (r) > 7 ? 1 : 0; \
+ int rm_ = (rm) > 7 ? 1 : 0; \
+ if ((w) | r_ | rm_) \
+ EMIT_REX(1, r_, 0, rm_); \
+} while (0)
+
+#ifndef _WIN32
+
+#define host_arg2reg(rd, arg) \
+ switch (arg) { \
+ case 0: rd = xDI; break; \
+ case 1: rd = xSI; break; \
+ case 2: rd = xDX; break; \
+ }
+
+#define emith_sh2_drc_entry() { \
+ emith_push(xBX); \
+ emith_push(xBP); \
+ emith_push(xSI); /* to align */ \
+}
+
+#define emith_sh2_drc_exit() { \
+ emith_pop(xSI); \
+ emith_pop(xBP); \
+ emith_pop(xBX); \
+ emith_ret(); \
+}
+
+#else // _WIN32
+
+#define host_arg2reg(rd, arg) \
+ switch (arg) { \
+ case 0: rd = xCX; break; \
+ case 1: rd = xDX; break; \
+ case 2: rd = 8; break; \
+ }
+
+#define emith_sh2_drc_entry() { \
+ emith_push(xBX); \
+ emith_push(xBP); \
+ emith_push(xSI); \
+ emith_push(xDI); \
+ emith_add_r_r_ptr_imm(xSP, xSP, -8*5); \
+}
+
+#define emith_sh2_drc_exit() { \
+ emith_add_r_r_ptr_imm(xSP, xSP, 8*5); \
+ emith_pop(xDI); \
+ emith_pop(xSI); \
+ emith_pop(xBP); \
+ emith_pop(xBX); \
+ emith_ret(); \
+}
+
+#endif // _WIN32
+
+#else // !__x86_64__
+
+#define PTR_SCALE 2
+#define NA_TMP_REG xBX // non-arg tmp from reg_temp[]
+
+#define EMIT_REX_IF(w, r, rm) do { \
+ assert((u32)(r) < 8u); \
+ assert((u32)(rm) < 8u); \
+} while (0)
+