# b base register (used in address references)
# f floating point register
# a EAX register
-# d EDX register
+# d EDX register
# l long reg (forced eax:edx)
-# s ECX register
-# c register which can be used as a byte register (RAX..RDX)
+# s ECX register
+# c register which can be used as a byte register (RAX..RDX)
+# A - first arg reg (rdi/rcx)
#
# len:number describe the maximun length in bytes of the instruction
# number is a positive integer. If the length is not specified
gc_spill_slot_liveness_def: len:0
gc_param_slot_liveness_def: len:0
-generic_class_init: src1:i len:32
+generic_class_init: src1:A len:32
emit_generic_class_init (MonoCompile *cfg, MonoClass *klass)
{
MonoInst *vtable_arg;
- MonoCallInst *call;
int context_used;
context_used = mini_class_check_context_used (cfg, klass);
#ifdef MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT
MonoInst *ins;
+ /*
+ * Using an opcode instead of emitting IR here allows the hiding of the call inside the opcode,
+ * so this doesn't have to clobber any regs.
+ */
/*
* For LLVM, this requires that the code in the generic trampoline obtain the vtable argument according to
* the normal calling convention of the platform.
ins->sreg1 = vtable_arg->dreg;
MONO_ADD_INS (cfg->cbb, ins);
#else
+ MonoCallInst *call;
+
if (COMPILE_LLVM (cfg))
call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_GENERIC_CLASS_INIT, NULL, helper_sig_generic_class_init_trampoline_llvm, &vtable_arg);
else
static guint8 bitmask;
guint8 *jump;
+ g_assert (ins->sreg1 == MONO_AMD64_ARG_REG1);
+
if (byte_offset < 0)
mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
jump = code;
amd64_branch8 (code, X86_CC_NZ, -1, 1);
- if (ins->sreg1 != MONO_AMD64_ARG_REG1)
- amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, ins->sreg1, 8);
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_generic_class_init", FALSE);
ins->flags |= MONO_INST_GC_CALLSITE;
ins->backend.pc_offset = code - cfg->native_code;
#define MONO_ARCH_USE_FPSTACK FALSE
#define MONO_ARCH_FPSTACK_SIZE 0
-#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == '\0') ? -1 : ((desc == 'i' ? -1 : ((desc == 'a') ? AMD64_RAX : ((desc == 's') ? AMD64_RCX : ((desc == 'd') ? AMD64_RDX : -1))))))
+#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == '\0') ? -1 : ((desc == 'i' ? -1 : ((desc == 'a') ? AMD64_RAX : ((desc == 's') ? AMD64_RCX : ((desc == 'd') ? AMD64_RDX : ((desc == 'A') ? MONO_AMD64_ARG_REG1 : -1)))))))
/* RDX is clobbered by the opcode implementation before accessing sreg2 */
#define MONO_ARCH_INST_SREG2_MASK(ins) (((ins [MONO_INST_CLOB] == 'a') || (ins [MONO_INST_CLOB] == 'd')) ? (1 << AMD64_RDX) : 0)