summaryrefslogtreecommitdiff
path: root/src/jit/target.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/target.h')
-rw-r--r--src/jit/target.h152
1 files changed, 94 insertions, 58 deletions
diff --git a/src/jit/target.h b/src/jit/target.h
index 5838cdda88..45bc1013a6 100644
--- a/src/jit/target.h
+++ b/src/jit/target.h
@@ -366,7 +366,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define ALIGN_SIMD_TYPES 1 // whether SIMD type locals are to be aligned
#endif // FEATURE_SIMD
- #define FEATURE_WRITE_BARRIER 1 // Generate the proper WriteBarrier calls for GC
#define FEATURE_FIXED_OUT_ARGS 0 // X86 uses push instructions to pass args
#define FEATURE_STRUCTPROMOTE 1 // JIT Optimization to promote fields of structs into registers
#define FEATURE_MULTIREG_STRUCT_PROMOTE 0 // True when we want to promote fields of a multireg struct into registers
@@ -510,11 +509,13 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_VAR_ORDER REG_EAX,REG_EDX,REG_ECX,REG_ESI,REG_EDI,REG_EBX
#define MAX_VAR_ORDER_SIZE 6
+
+#ifdef LEGACY_BACKEND
#define REG_TMP_ORDER REG_EAX,REG_EDX,REG_ECX,REG_EBX,REG_ESI,REG_EDI
- #define RBM_TMP_ORDER RBM_EAX,RBM_EDX,RBM_ECX,RBM_EBX,RBM_ESI,RBM_EDI
#define REG_TMP_ORDER_COUNT 6
#define REG_PREDICT_ORDER REG_EAX,REG_EDX,REG_ECX,REG_EBX,REG_ESI,REG_EDI
+#endif // LEGACY_BACKEND
// The order here is fixed: it must agree with an order assumed in eetwain...
#define REG_CALLEE_SAVED_ORDER REG_EDI,REG_ESI,REG_EBX,REG_EBP
@@ -743,7 +744,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define FEATURE_PARTIAL_SIMD_CALLEE_SAVE 1 // Whether SIMD registers are partially saved at calls
#endif // !UNIX_AMD64_ABI
#endif
- #define FEATURE_WRITE_BARRIER 1 // Generate the WriteBarrier calls for GC (currently not the x86-style register-customized barriers)
#define FEATURE_FIXED_OUT_ARGS 1 // Preallocate the outgoing arg area in the prolog
#define FEATURE_STRUCTPROMOTE 1 // JIT Optimization to promote fields of structs into registers
#define FEATURE_MULTIREG_STRUCT_PROMOTE 0 // True when we want to promote fields of a multireg struct into registers
@@ -770,11 +770,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define MAX_RET_REG_COUNT 1 // Maximum registers used to return a value.
#endif // !UNIX_AMD64_ABI
-#ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS
#define NOGC_WRITE_BARRIERS 0 // We DO-NOT have specialized WriteBarrier JIT Helpers that DO-NOT trash the RBM_CALLEE_TRASH registers
-#else
- #define NOGC_WRITE_BARRIERS 0 // Do not modify this -- modify the definition above. (If we're not using ASM barriers we definitely don't have NOGC barriers).
-#endif
#define USER_ARGS_COME_LAST 1
#define EMIT_TRACK_STACK_DEPTH 1
#define TARGET_POINTER_SIZE 8 // equal to sizeof(void*) and the managed pointer size in bytes for this target
@@ -882,17 +878,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_VAR_ORDER_FLT REG_XMM0,REG_XMM1,REG_XMM2,REG_XMM3,REG_XMM4,REG_XMM5,REG_XMM6,REG_XMM7,REG_XMM8,REG_XMM9,REG_XMM10,REG_XMM11,REG_XMM12,REG_XMM13,REG_XMM14,REG_XMM15
#ifdef UNIX_AMD64_ABI
- #define REG_TMP_ORDER REG_EAX,REG_EDI,REG_ESI,REG_EDX,REG_ECX,REG_EBX,REG_ETW_FRAMED_EBP_LIST \
- REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
-#else // !UNIX_AMD64_ABI
- #define MAX_VAR_ORDER_SIZE (14 + REG_ETW_FRAMED_EBP_COUNT)
- #define REG_TMP_ORDER REG_EAX,REG_EDX,REG_ECX,REG_EBX,REG_ESI,REG_EDI,REG_ETW_FRAMED_EBP_LIST \
- REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
-#endif // !UNIX_AMD64_ABI
-
-#ifdef UNIX_AMD64_ABI
- #define REG_PREDICT_ORDER REG_EAX,REG_EDI,REG_ESI,REG_EDX,REG_ECX,REG_EBX,REG_ETW_FRAMED_EBP_LIST \
- REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#define CNT_CALLEE_SAVED (5 + REG_ETW_FRAMED_EBP_COUNT)
#define CNT_CALLEE_TRASH (9)
#define CNT_CALLEE_ENREG (CNT_CALLEE_SAVED)
@@ -903,9 +888,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_CALLEE_SAVED_ORDER REG_EBX,REG_ETW_FRAMED_EBP_LIST REG_R12,REG_R13,REG_R14,REG_R15
#define RBM_CALLEE_SAVED_ORDER RBM_EBX,RBM_ETW_FRAMED_EBP_LIST RBM_R12,RBM_R13,RBM_R14,RBM_R15
#else // !UNIX_AMD64_ABI
- #define REG_TMP_ORDER_COUNT (14 + REG_ETW_FRAMED_EBP_COUNT)
- #define REG_PREDICT_ORDER REG_EAX,REG_EDX,REG_ECX,REG_EBX,REG_ESI,REG_EDI,REG_ETW_FRAMED_EBP_LIST \
- REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#define CNT_CALLEE_SAVED (7 + REG_ETW_FRAMED_EBP_COUNT)
#define CNT_CALLEE_TRASH (7)
#define CNT_CALLEE_ENREG (CNT_CALLEE_SAVED)
@@ -969,11 +951,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_JUMP_THUNK_PARAM REG_EAX
#define RBM_JUMP_THUNK_PARAM RBM_EAX
-#if NOGC_WRITE_BARRIERS
- #define REG_WRITE_BARRIER REG_EDX
- #define RBM_WRITE_BARRIER RBM_EDX
-#endif
-
// Register to be used for emitting helper calls whose call target is an indir of an
// absolute memory address in case of Rel32 overflow i.e. a data address could not be
// encoded as PC-relative 32-bit offset.
@@ -991,12 +968,10 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
// GenericPInvokeCalliHelper VASigCookie Parameter
#define REG_PINVOKE_COOKIE_PARAM REG_R11
#define RBM_PINVOKE_COOKIE_PARAM RBM_R11
- #define PREDICT_REG_PINVOKE_COOKIE_PARAM PREDICT_REG_R11
// GenericPInvokeCalliHelper unmanaged target Parameter
#define REG_PINVOKE_TARGET_PARAM REG_R10
#define RBM_PINVOKE_TARGET_PARAM RBM_R10
- #define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R10
// IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM)
#define REG_SECRET_STUB_PARAM REG_R10
@@ -1188,7 +1163,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define CPBLK_UNROLL_LIMIT 32 // Upper bound to let the code generator to loop unroll CpBlk.
#define INITBLK_UNROLL_LIMIT 32 // Upper bound to let the code generator to loop unroll InitBlk.
- #define FEATURE_WRITE_BARRIER 1 // Generate the proper WriteBarrier calls for GC
#define FEATURE_FIXED_OUT_ARGS 1 // Preallocate the outgoing arg area in the prolog
#define FEATURE_STRUCTPROMOTE 1 // JIT Optimization to promote fields of structs into registers
#define FEATURE_MULTIREG_STRUCT_PROMOTE 0 // True when we want to promote fields of a multireg struct into registers
@@ -1204,11 +1178,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define MAX_ARG_REG_COUNT 4 // Maximum registers used to pass a single argument in multiple registers. (max is 4 floats or doubles using an HFA)
#define MAX_RET_REG_COUNT 4 // Maximum registers used to return a value.
-#ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS
#define NOGC_WRITE_BARRIERS 0 // We DO-NOT have specialized WriteBarrier JIT Helpers that DO-NOT trash the RBM_CALLEE_TRASH registers
-#else
- #define NOGC_WRITE_BARRIERS 0 // Do not modify this -- modify the definition above. (If we're not using ASM barriers we definitely don't have NOGC barriers).
-#endif
#define USER_ARGS_COME_LAST 1
#define EMIT_TRACK_STACK_DEPTH 1 // This is something of a workaround. For both ARM and AMD64, the frame size is fixed, so we don't really
// need to track stack depth, but this is currently necessary to get GC information reported at call sites.
@@ -1247,8 +1217,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_DEFAULT_HELPER_CALL_TARGET REG_R12
#define RBM_DEFAULT_HELPER_CALL_TARGET RBM_R12
- #define RBM_CALLEE_TRASH_NOGC (RBM_R2|RBM_R3|RBM_LR|RBM_DEFAULT_HELPER_CALL_TARGET)
-
#define REG_FASTTAILCALL_TARGET REG_R12 // Target register for fast tail call
#define RBM_FASTTAILCALL_TARGET RBM_R12
@@ -1268,6 +1236,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
REG_F24, REG_F25, REG_F26, REG_F27, \
REG_F28, REG_F29, REG_F30, REG_F31,
+#ifdef LEGACY_BACKEND
#define MAX_VAR_ORDER_SIZE 32
#define REG_TMP_ORDER REG_R3,REG_R2,REG_R1,REG_R0, REG_R4,REG_R5,REG_R6,REG_R7,\
@@ -1287,6 +1256,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_PREDICT_ORDER REG_LR,REG_R12,REG_R3,REG_R2,REG_R1,REG_R0, \
REG_R7,REG_R6,REG_R5,REG_R4,REG_R8,REG_R9,REG_R10
+#endif // LEGACY_BACKEND
#define RBM_LOW_REGS (RBM_R0|RBM_R1|RBM_R2|RBM_R3|RBM_R4|RBM_R5|RBM_R6|RBM_R7)
#define RBM_HIGH_REGS (RBM_R8|RBM_R9|RBM_R10|RBM_R11|RBM_R12|RBM_SP|RBM_LR|RBM_PC)
@@ -1371,27 +1341,60 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_JUMP_THUNK_PARAM REG_R12
#define RBM_JUMP_THUNK_PARAM RBM_R12
-#if NOGC_WRITE_BARRIERS
- #define REG_WRITE_BARRIER REG_R1
- #define RBM_WRITE_BARRIER RBM_R1
-#endif
+ // ARM write barrier ABI (see vm\arm\asmhelpers.asm, vm\arm\asmhelpers.S):
+ // CORINFO_HELP_ASSIGN_REF (JIT_WriteBarrier), CORINFO_HELP_CHECKED_ASSIGN_REF (JIT_CheckedWriteBarrier):
+ // On entry:
+ // r0: the destination address (LHS of the assignment)
+ // r1: the object reference (RHS of the assignment)
+ // On exit:
+ // r0: trashed
+ // r3: trashed
+ // CORINFO_HELP_ASSIGN_BYREF (JIT_ByRefWriteBarrier):
+ // On entry:
+ // r0: the destination address (object reference written here)
+ // r1: the source address (points to object reference to write)
+ // On exit:
+ // r0: incremented by 4
+ // r1: incremented by 4
+ // r2: trashed
+ // r3: trashed
+
+ #define REG_WRITE_BARRIER_DST_BYREF REG_ARG_0
+ #define RBM_WRITE_BARRIER_DST_BYREF RBM_ARG_0
- //In the ARM case, registers of write barrier use the normal argument registers.
#define REG_WRITE_BARRIER_SRC_BYREF REG_ARG_1
#define RBM_WRITE_BARRIER_SRC_BYREF RBM_ARG_1
- #define REG_WRITE_BARRIER_DST_BYREF REG_ARG_0
- #define RBM_WRITE_BARRIER_DST_BYREF RBM_ARG_0
+ #define RBM_CALLEE_TRASH_NOGC (RBM_R2|RBM_R3|RBM_LR|RBM_DEFAULT_HELPER_CALL_TARGET)
+
+ // Registers killed by CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
+ #define RBM_CALLEE_TRASH_WRITEBARRIER (RBM_R0|RBM_R3|RBM_LR|RBM_DEFAULT_HELPER_CALL_TARGET)
+
+ // Registers no longer containing GC pointers after CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
+ #define RBM_CALLEE_GCTRASH_WRITEBARRIER RBM_CALLEE_TRASH_WRITEBARRIER
+
+ // Registers killed by CORINFO_HELP_ASSIGN_BYREF.
+ #define RBM_CALLEE_TRASH_WRITEBARRIER_BYREF (RBM_WRITE_BARRIER_DST_BYREF | RBM_WRITE_BARRIER_SRC_BYREF | RBM_CALLEE_TRASH_NOGC)
+
+ // Registers no longer containing GC pointers after CORINFO_HELP_ASSIGN_BYREF.
+ // Note that r0 and r1 are still valid byref pointers after this helper call, despite their value being changed.
+ #define RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF RBM_CALLEE_TRASH_NOGC
// GenericPInvokeCalliHelper VASigCookie Parameter
#define REG_PINVOKE_COOKIE_PARAM REG_R4
#define RBM_PINVOKE_COOKIE_PARAM RBM_R4
+
+#ifdef LEGACY_BACKEND
#define PREDICT_REG_PINVOKE_COOKIE_PARAM PREDICT_REG_R4
+#endif // LEGACY_BACKEND
// GenericPInvokeCalliHelper unmanaged target Parameter
#define REG_PINVOKE_TARGET_PARAM REG_R12
#define RBM_PINVOKE_TARGET_PARAM RBM_R12
+
+#ifdef LEGACY_BACKEND
#define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R12
+#endif // LEGACY_BACKEND
// IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM)
#define REG_SECRET_STUB_PARAM REG_R12
@@ -1546,7 +1549,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define FEATURE_PARTIAL_SIMD_CALLEE_SAVE 1 // Whether SIMD registers are partially saved at calls
#endif // FEATURE_SIMD
- #define FEATURE_WRITE_BARRIER 1 // Generate the proper WriteBarrier calls for GC
#define FEATURE_FIXED_OUT_ARGS 1 // Preallocate the outgoing arg area in the prolog
#define FEATURE_STRUCTPROMOTE 1 // JIT Optimization to promote fields of structs into registers
#define FEATURE_MULTIREG_STRUCT_PROMOTE 1 // True when we want to promote fields of a multireg struct into registers
@@ -1562,11 +1564,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define MAX_ARG_REG_COUNT 4 // Maximum registers used to pass a single argument in multiple registers. (max is 4 floats or doubles using an HFA)
#define MAX_RET_REG_COUNT 4 // Maximum registers used to return a value.
-#ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS
#define NOGC_WRITE_BARRIERS 1 // We have specialized WriteBarrier JIT Helpers that DO-NOT trash the RBM_CALLEE_TRASH registers
-#else
- #define NOGC_WRITE_BARRIERS 0 // Do not modify this -- modify the definition above. (If we're not using ASM barriers we definitely don't have NOGC barriers).
-#endif
#define USER_ARGS_COME_LAST 1
#define EMIT_TRACK_STACK_DEPTH 1 // This is something of a workaround. For both ARM and AMD64, the frame size is fixed, so we don't really
// need to track stack depth, but this is currently necessary to get GC information reported at call sites.
@@ -1608,9 +1606,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_DEFAULT_HELPER_CALL_TARGET REG_R12
#define RBM_DEFAULT_HELPER_CALL_TARGET RBM_R12
- // REVIEW: why does arm64 RBM_CALLEE_TRASH_NOGC include IP1? The JIT_ByRefWriteBarrier only trashes r12 and r15.
- #define RBM_CALLEE_TRASH_NOGC (RBM_R12|RBM_R15|RBM_IP1|RBM_DEFAULT_HELPER_CALL_TARGET)
-
#define REG_FASTTAILCALL_TARGET REG_IP0 // Target register for fast tail call
#define RBM_FASTTAILCALL_TARGET RBM_IP0
@@ -1679,26 +1674,65 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_JUMP_THUNK_PARAM REG_R12
#define RBM_JUMP_THUNK_PARAM RBM_R12
-#if NOGC_WRITE_BARRIERS
- #define REG_WRITE_BARRIER_SRC_BYREF REG_R13
- #define RBM_WRITE_BARRIER_SRC_BYREF RBM_R13
+ // ARM64 write barrier ABI (see vm\arm64\asmhelpers.asm, vm\arm64\asmhelpers.S):
+ // CORINFO_HELP_ASSIGN_REF (JIT_WriteBarrier), CORINFO_HELP_CHECKED_ASSIGN_REF (JIT_CheckedWriteBarrier):
+ // On entry:
+ // x14: the destination address (LHS of the assignment)
+ // x15: the object reference (RHS of the assignment)
+ // On exit:
+ // x12: trashed
+ // x14: incremented by 8
+ // x15: trashed
+ // x17: trashed (ip1) if FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP (currently non-Windows)
+ // CORINFO_HELP_ASSIGN_BYREF (JIT_ByRefWriteBarrier):
+ // On entry:
+ // x13: the source address (points to object reference to write)
+ // x14: the destination address (object reference written here)
+ // On exit:
+ // x12: trashed
+ // x13: incremented by 8
+ // x14: incremented by 8
+ // x15: trashed
+ // x17: trashed (ip1) if FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP (currently non-Windows)
+ //
+ // Note that while x17 (ip1) is currently only trashed under FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP,
+ // currently only set for non-Windows, it is expected to be set in the future for Windows, and for R2R.
+ // So simply always consider it trashed, to avoid later breaking changes.
+
+ #define REG_WRITE_BARRIER_DST REG_R14
+ #define RBM_WRITE_BARRIER_DST RBM_R14
+
+ #define REG_WRITE_BARRIER_SRC REG_R15
+ #define RBM_WRITE_BARRIER_SRC RBM_R15
#define REG_WRITE_BARRIER_DST_BYREF REG_R14
#define RBM_WRITE_BARRIER_DST_BYREF RBM_R14
- #define REG_WRITE_BARRIER REG_R15
- #define RBM_WRITE_BARRIER RBM_R15
-#endif
+ #define REG_WRITE_BARRIER_SRC_BYREF REG_R13
+ #define RBM_WRITE_BARRIER_SRC_BYREF RBM_R13
+
+ #define RBM_CALLEE_TRASH_NOGC (RBM_R12|RBM_R15|RBM_IP1|RBM_DEFAULT_HELPER_CALL_TARGET)
+
+ // Registers killed by CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
+ #define RBM_CALLEE_TRASH_WRITEBARRIER (RBM_R14|RBM_CALLEE_TRASH_NOGC)
+
+ // Registers no longer containing GC pointers after CORINFO_HELP_ASSIGN_REF and CORINFO_HELP_CHECKED_ASSIGN_REF.
+ #define RBM_CALLEE_GCTRASH_WRITEBARRIER RBM_CALLEE_TRASH_NOGC
+
+ // Registers killed by CORINFO_HELP_ASSIGN_BYREF.
+ #define RBM_CALLEE_TRASH_WRITEBARRIER_BYREF (RBM_WRITE_BARRIER_DST_BYREF | RBM_WRITE_BARRIER_SRC_BYREF | RBM_CALLEE_TRASH_NOGC)
+
+ // Registers no longer containing GC pointers after CORINFO_HELP_ASSIGN_BYREF.
+ // Note that x13 and x14 are still valid byref pointers after this helper call, despite their value being changed.
+ #define RBM_CALLEE_GCTRASH_WRITEBARRIER_BYREF RBM_CALLEE_TRASH_NOGC
// GenericPInvokeCalliHelper VASigCookie Parameter
#define REG_PINVOKE_COOKIE_PARAM REG_R15
#define RBM_PINVOKE_COOKIE_PARAM RBM_R15
- #define PREDICT_REG_PINVOKE_COOKIE_PARAM PREDICT_REG_R15
// GenericPInvokeCalliHelper unmanaged target Parameter
#define REG_PINVOKE_TARGET_PARAM REG_R14
#define RBM_PINVOKE_TARGET_PARAM RBM_R14
- #define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R14
// IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM)
#define REG_SECRET_STUB_PARAM REG_R12
@@ -1919,6 +1953,7 @@ public:
};
static const enum ArgOrder g_tgtArgOrder;
+#ifdef LEGACY_BACKEND
#if NOGC_WRITE_BARRIERS
static regMaskTP exclude_WriteBarrierReg(regMaskTP mask)
{
@@ -1929,6 +1964,7 @@ public:
return RBM_ALLINT & ~RBM_WRITE_BARRIER;
}
#endif // NOGC_WRITE_BARRIERS
+#endif // LEGACY_BACKEND
};
#if defined(DEBUG) || defined(LATE_DISASM)