X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-s390x.h;h=5274d34536662f94fda060fbf5b03a7bf2e7e29a;hb=279b47e476642431c7f96e105ed32f133d6ed5a3;hp=77c190b571cf906bcda5a3e9dd277aced48c3958;hpb=ea0385c659ff0c455b0424ae9ec527f0582e7b67;p=mono.git diff --git a/mono/mini/mini-s390x.h b/mono/mini/mini-s390x.h index 77c190b571c..5274d345366 100644 --- a/mono/mini/mini-s390x.h +++ b/mono/mini/mini-s390x.h @@ -4,10 +4,14 @@ #include #include +#define MONO_ARCH_CPU_SPEC s390x_cpu_desc + #define MONO_MAX_IREGS 16 #define MONO_MAX_FREGS 16 -#define MONO_ARCH_FRAME_ALIGNMENT 8 +/*-------------------------------------------*/ +/* Parameters used by the register allocator */ +/*-------------------------------------------*/ #define MONO_EMIT_NEW_MOVE(cfg,dest,offset,src,imm,size) do { \ MonoInst *inst; \ @@ -46,27 +50,36 @@ } \ } \ inst->opcode = OP_S390_MOVE; \ - inst->unused = size; \ + inst->backend.size = size; \ mono_bblock_add_inst (cfg->cbb, inst); \ } while (0) #define MONO_OUTPUT_VTR(cfg, size, dr, sr, so) do { \ + int reg = mono_regstate_next_int (cfg->rs); \ switch (size) { \ + case 0: \ + MONO_EMIT_NEW_ICONST(cfg, reg, 0); \ + mono_call_inst_add_outarg_reg(s, call, reg, dr, FALSE); \ + break; \ case 1: \ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE, \ - dr, sr, so); \ + reg, sr, so); \ + mono_call_inst_add_outarg_reg(s, call, reg, dr, FALSE); \ break; \ case 2: \ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE, \ - dr, sr, so); \ + reg, sr, so); \ + mono_call_inst_add_outarg_reg(s, call, reg, dr, FALSE); \ break; \ case 4: \ - MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU4_MEMBASE, \ - dr, sr, so); \ + MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADI4_MEMBASE, \ + reg, sr, so); \ + mono_call_inst_add_outarg_reg(s, call, reg, dr, FALSE); \ break; \ case 8: \ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \ - dr, sr, so); \ + reg, sr, so); \ + mono_call_inst_add_outarg_reg(s, call, reg, dr, FALSE); \ break; \ } \ } while (0) @@ -74,30 +87,61 @@ #define MONO_OUTPUT_VTS(cfg, size, dr, dx, sr, so) do { \ int tmpr; \ switch (size) { \ + case 0: \ + tmpr = mono_regstate_next_int (cfg->rs); \ + MONO_EMIT_NEW_ICONST(cfg, tmpr, 0); \ + MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \ + dr, dx, tmpr); \ + break; \ case 1: \ tmpr = mono_regstate_next_int (cfg->rs); \ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE, \ tmpr, sr, so); \ MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \ - tmpr, dr, dx); \ + dr, dx, tmpr); \ break; \ case 2: \ tmpr = mono_regstate_next_int (cfg->rs); \ MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE, \ tmpr, sr, so); \ MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \ - tmpr, dr, dx); \ + dr, dx, tmpr); \ break; \ case 4: \ + tmpr = mono_regstate_next_int (cfg->rs); \ + MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADI4_MEMBASE, \ + tmpr, sr, so); \ + MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \ + dr, dx, tmpr); \ + break; \ case 8: \ MONO_EMIT_NEW_MOVE (cfg, dr, dx, sr, so, size); \ break; \ } \ } while (0) -/* fixme: align to 16byte instead of 32byte (we align to 32byte to get - * reproduceable results for benchmarks */ -#define MONO_ARCH_CODE_ALIGNMENT 32 +#define S390_LONG(loc, opy, op, r, ix, br, off) \ + if (has_ld) { \ + if (s390_is_imm20(off)) { \ + s390_##opy (loc, r, ix, br, off); \ + } else { \ + s390_basr (code, s390_r13, 0); \ + s390_j (code, 6); \ + s390_llong(code, off); \ + s390_lg (code, s390_r13, 0, s390_r13, 4); \ + s390_##op (code, r, s390_r13, br, 0); \ + } \ + } else { \ + if (s390_is_uimm12(off)) { \ + s390_##op (loc, r, ix, br, off); \ + } else { \ + s390_basr (code, s390_r13, 0); \ + s390_j (code, 6); \ + s390_llong(code, off); \ + s390_lg (code, s390_r13, 0, s390_r13, 4); \ + s390_##op (code, r, s390_r13, br, 0); \ + } \ + } struct MonoLMF { gpointer previous_lmf; @@ -105,6 +149,7 @@ struct MonoLMF { MonoMethod *method; gulong ebp; gulong eip; + gulong pregs[6]; gulong gregs[16]; gdouble fregs[16]; }; @@ -112,14 +157,31 @@ struct MonoLMF { typedef struct ucontext MonoContext; typedef struct MonoCompileArch { + gpointer litpool; + glong litsize; + int bkchain_reg; } MonoCompileArch; -#define MONO_ARCH_EMULATE_FCONV_TO_I8 1 -#define MONO_ARCH_EMULATE_LCONV_TO_R8 1 -#define MONO_ARCH_EMULATE_LCONV_TO_R4 1 -#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1 -#define MONO_ARCH_EMULATE_LMUL 1 -#define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1 +typedef struct +{ + void *prev; + void *unused[5]; + void *regs[8]; + void *return_address; +} MonoS390StackFrame; + +// #define MONO_ARCH_SIGSEGV_ON_ALTSTACK 1 +#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1 +#define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS 1 +#define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1 +#define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1 +#define MONO_ARCH_NEED_DIV_CHECK 1 +#define MONO_ARCH_HAVE_ATOMIC_ADD 1 +#define MONO_ARCH_HAVE_ATOMIC_EXCHANGE 1 +#define MONO_ARCH_SIGNAL_STACK_SIZE 256*1024 +#define MONO_ARCH_HAVE_DECOMPOSE_OPTS 1 +#define MONO_ARCH_ENABLE_NORMALIZE_OPCODES 1 +// #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1 #define MONO_ARCH_USE_SIGACTION 1 @@ -127,30 +189,174 @@ typedef struct MonoCompileArch { #define S390_FIRST_ARG_REG s390_r2 #define S390_LAST_ARG_REG s390_r6 #define S390_FIRST_FPARG_REG s390_f0 -#define S390_LAST_FPARG_REG s390_f2 +#define S390_LAST_FPARG_REG s390_f6 #define S390_PASS_STRUCTS_BY_VALUE 1 #define S390_SMALL_RET_STRUCT_IN_REG 1 #define S390_NUM_REG_ARGS (S390_LAST_ARG_REG-S390_FIRST_ARG_REG+1) -#define S390_NUM_REG_FPARGS (S390_LAST_FPARG_REG-S390_FIRST_FPARG_REG) +#define S390_NUM_REG_FPARGS ((S390_LAST_FPARG_REG-S390_FIRST_FPARG_REG)/2) + +/*===============================================*/ +/* Definitions used by mini-codegen.c */ +/*===============================================*/ + +/*------------------------------------------------------*/ +/* use s390_r2-s390_r6 as parm registers */ +/* s390_r0, s390_r1, s390_r12, s390_r13 used internally */ +/* s390_r8..s390_r11 are used for global regalloc */ +/* s390_r15 is the stack pointer */ +/*------------------------------------------------------*/ +#define MONO_ARCH_CALLEE_REGS (0xfc) + +#define MONO_ARCH_CALLEE_SAVED_REGS 0xff80 + +/*----------------------------------------*/ +/* use s390_f1/s390_f3-s390_f15 as temps */ +/*----------------------------------------*/ + +#define MONO_ARCH_CALLEE_FREGS (0xfffe) + +#define MONO_ARCH_CALLEE_SAVED_FREGS 0 + +#define MONO_ARCH_USE_FPSTACK FALSE +#define MONO_ARCH_FPSTACK_SIZE 0 + +#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? s390_r2 : \ + ((desc == 'g') ? s390_f0 : - 1)) + +#define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g')) -#define S390_OFFSET(b, t) (gint32) ((gint64) (b) - (gint64) (t)) -#define S390_RELATIVE(b, t) (gint32) ((((gint64) (b) - (gint64) (t))) / 2) +#define MONO_ARCH_INST_SREG2_MASK(ins) (0) -#define CODEPTR(c, o) (o) = (short *) ((gint64) c - 2) -#define PTRSLOT(c, o) *(o) = (short) ((gint64) c - (gint64) (o) + 2)/2 +#define MONO_ARCH_INST_IS_REGPAIR(desc) (0) +#define MONO_ARCH_INST_REGPAIR_REG2(desc,hr) -1 + +#define MONO_ARCH_IS_GLOBAL_IREG(reg) 0 + +#define MONO_ARCH_FRAME_ALIGNMENT 8 +#define MONO_ARCH_CODE_ALIGNMENT 32 + +#define MONO_ARCH_BASEREG s390_r15 +#define MONO_ARCH_RETREG1 s390_r2 + +/*-----------------------------------------------*/ +/* Macros used to generate instructions */ +/*-----------------------------------------------*/ +#define S390_OFFSET(b, t) (guchar *) ((guint64) (b) - (guint64) (t)) +#define S390_RELATIVE(b, t) (guchar *) ((((guint64) (b) - (guint64) (t))) / 2) + +#define CODEPTR(c, o) (o) = (short *) ((guint64) c - 2) +#define PTRSLOT(c, o) *(o) = (short) ((guint64) c - (guint64) (o) + 2)/2 #define S390_CC_EQ 8 #define S390_ALIGN(v, a) (((a) > 0 ? (((v) + ((a) - 1)) & ~((a) - 1)) : (v))) +#define MONO_CONTEXT_SET_IP(ctx,ip) \ + do { \ + (ctx)->uc_mcontext.gregs[14] = (unsigned long)ip; \ + (ctx)->uc_mcontext.psw.addr = (unsigned long)ip; \ + } while (0); + +#define MONO_CONTEXT_SET_SP(ctx,bp) MONO_CONTEXT_SET_BP((ctx),(bp)) +#define MONO_CONTEXT_SET_BP(ctx,bp) \ + do { \ + (ctx)->uc_mcontext.gregs[15] = (unsigned long)bp; \ + (ctx)->uc_stack.ss_sp = (void*)bp; \ + } while (0) + +#define MONO_CONTEXT_GET_IP(ctx) (gpointer) (ctx)->uc_mcontext.psw.addr +#define MONO_CONTEXT_GET_BP(ctx) MONO_CONTEXT_GET_SP((ctx)) +#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.gregs[15])) + +#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do { \ + MonoS390StackFrame *sframe; \ + __asm__ volatile("lgr %0,15" : "=r" (sframe)); \ + MONO_CONTEXT_SET_BP ((ctx), sframe->prev); \ + MONO_CONTEXT_SET_SP ((ctx), sframe->prev); \ + sframe = (MonoS390StackFrame*)sframe->prev; \ + MONO_CONTEXT_SET_IP ((ctx), sframe->return_address); \ + } while (0) + +/*------------------------------------------------------------------*/ +/* */ +/* Name - s390_patch_rel */ +/* */ +/* Function - Patch the code with a given offset. */ +/* */ +/*------------------------------------------------------------------*/ + static void inline -s390_patch (guchar *code, gint32 target) +s390_patch_rel (guchar *code, guint64 target) { - gint32 *offset = (gint32 *) code; + guint32 *offset = (guint32 *) code; - if (target != 00) { + if (target != 0) { + *offset = (guint32) target; + } +} + +/*========================= End of Function ========================*/ + +/*------------------------------------------------------------------*/ +/* */ +/* Name - s390_patch_addr */ +/* */ +/* Function - Patch the code with a given address. */ +/* */ +/*------------------------------------------------------------------*/ + +static void inline +s390_patch_addr (guchar *code, guint64 target) +{ + guint64 *offset = (guint64 *) code; + + if (target != 0) { *offset = target; } } -#endif /* __MONO_MINI_S390_H__ */ +/*========================= End of Function ========================*/ + +/*------------------------------------------------------------------*/ +/* */ +/* Name - restoreLMF */ +/* */ +/* Function - Restore the LMF state prior to exiting a method. */ +/* */ +/*------------------------------------------------------------------*/ + +#define restoreLMF(code, frame_reg, stack_usage) do \ +{ \ + int lmfOffset = 0; \ + \ + s390_lgr (code, s390_r13, frame_reg); \ + \ + lmfOffset = stack_usage - sizeof(MonoLMF); \ + \ + /*-------------------------------------------------*/ \ + /* r13 = my lmf */ \ + /*-------------------------------------------------*/ \ + s390_aghi (code, s390_r13, lmfOffset); \ + \ + /*-------------------------------------------------*/ \ + /* r6 = &jit_tls->lmf */ \ + /*-------------------------------------------------*/ \ + s390_lg (code, s390_r6, 0, s390_r13, \ + G_STRUCT_OFFSET(MonoLMF, lmf_addr)); \ + \ + /*-------------------------------------------------*/ \ + /* r0 = lmf.previous_lmf */ \ + /*-------------------------------------------------*/ \ + s390_lg (code, s390_r0, 0, s390_r13, \ + G_STRUCT_OFFSET(MonoLMF, previous_lmf)); \ + \ + /*-------------------------------------------------*/ \ + /* jit_tls->lmf = previous_lmf */ \ + /*-------------------------------------------------*/ \ + s390_lg (code, s390_r13, 0, s390_r6, 0); \ + s390_stg (code, s390_r0, 0, s390_r6, 0); \ +} while (0) + +/*========================= End of Function ========================*/ + +#endif /* __MONO_MINI_S390X_H__ */