Re: [Mono-dev] mono-2.6.7 build on linux/alpha
furutaka wrote: Hi all, The only thing I know about mono is that it's an open-source .NET-compatible set of tools. Now I'm trying to build it on linux/alpha, specifically, Gentoo, and the build failed due to missing operands of MINI_OP() in mini-ops.h, as the following; (...) Hello, the code for alpha arch needs to be updated to support Linear IR. Latest working version was - 1.9.xxx. Unfortunately, I don't have spare time to do it, but could share some work that I've done already (I converted most of the operations, floating points ops has to be reworked). Thank you, -- Sergey Tikhonov Head, RD department Solvo Ltd. Saint-Petersburg, Russia http://www.solvo.ru t...@solvo.ru ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Patch for Oracle dataprovider
Hello, I got a instance where mono throw an exception working with Oracle. The problem is when I try to retrieve huge float from the database. Oracle data provider tries to use Number type to get the data. I tracked the problem down to usage of memory. It seems that size of allocated buffer passed to OCI call is 2 times than allocated. Allocating the buffer for the same size fixed that problem. Here is the patch. Thank you, -- Sergey Tikhonov Head, RD department Solvo Ltd. Saint-Petersburg, Russia http://www.solvo.ru t...@solvo.ru --- mono-2.2/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs.orig 2008-12-09 16:12:05.0 +0300 +++ mono-2.2/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs 2008-12-09 16:12:35.0 +0300 @@ -286,7 +286,7 @@ void DefineNumber (int position, OracleConnection connection) { fieldType = typeof (System.Decimal); - value = OciCalls.AllocateClear (definedSize); + value = OciCalls.AllocateClear (definedSize * 2); ociType = OciDataType.Char; ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] [Fwd: Mono/Alpha patches]
---BeginMessage--- Hello, Here are patches to bring the Mono/Alpha port to the current level. Thank you, Sergey. Index: mono/mono/mini/tramp-alpha.c === --- mono/mono/mini/tramp-alpha.c (revision 95543) +++ mono/mono/mini/tramp-alpha.c (working copy) @@ -181,7 +181,7 @@ } // alpha_at points to start of this method !!! -alpha_ldq(code, alpha_r0, alpha_at, off); +alpha_ldq(code, alpha_pv, alpha_at, off); alpha_br(code, alpha_zero, 2); *code = (unsigned int)(((unsigned long)mono_get_lmf_addr) 0x); @@ -193,7 +193,7 @@ * The call might clobber argument registers, but they are already * saved to the stack/global regs. */ -alpha_jsr(code, alpha_ra, alpha_r0, 0); +alpha_jsr(code, alpha_ra, alpha_pv, 0); // Save lmf_addr alpha_stq(code, alpha_r0, alpha_sp, Index: mono/mono/mini/mini-alpha.c === --- mono/mono/mini/mini-alpha.c (revision 95543) +++ mono/mono/mini/mini-alpha.c (working copy) @@ -25,9 +25,9 @@ #define ALPHA_PRINT if (mini_alpha_verbose_level) #define NEW_INS(cfg,ins,dest,op) do { \ - (dest) = mono_mempool_alloc0 ((cfg)-mempool, sizeof (MonoInst)); \ - (dest)-opcode = (op); \ - MONO_INST_LIST_ADD_TAIL ((dest)-node, (ins)-node); + (dest) = mono_mempool_alloc0 ((cfg)-mempool, sizeof (MonoInst));\ + (dest)-opcode = (op); \ + MONO_INST_LIST_ADD_TAIL ((dest)-node, (ins)-node); \ } while (0) #define NEW_ICONST(cfg,dest,val) do { \ @@ -91,6 +91,9 @@ gboolean lmf_addr_key_inited = FALSE; +MonoBreakpointInfo +mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE]; + /*== End of Global Variables ===*/ gpointer mono_arch_get_lmf_addr (void); @@ -191,7 +194,7 @@ } static void -add_valuetype (MonoGenericSharingContext *ctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, +add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, gboolean is_return, guint32 *gr, guint32 *fr, guint32 *stack_size) { @@ -419,17 +422,21 @@ /*= End of Function */ +// This peephole function is called before local_regalloc method +// TSV_TODO - Check what we need to move here void mono_arch_peephole_pass_1 (MonoCompile *cfg, MonoBasicBlock *bb) { + CFG_DEBUG(3) g_print (ALPHA: PEEPHOLE_1 pass\n); } +// This peephole function is called after local_regalloc method void mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb) { MonoInst *ins, *n; - CFG_DEBUG(3) g_print (ALPHA: PEEPHOLE pass\n); + CFG_DEBUG(3) g_print (ALPHA: PEEPHOLE_2 pass\n); MONO_INST_LIST_FOR_EACH_ENTRY_SAFE (ins, n, bb-ins_list, node) { MonoInst *last_ins = mono_inst_list_prev (ins-node, bb-ins_list); @@ -910,8 +917,8 @@ * Converts complex opcodes into simpler ones so that each IR instruction * corresponds to one machine instruction. */ -static void - mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) +void +mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) { MonoInst *ins, *n, *next, *temp; @@ -983,7 +990,7 @@ ins-sreg2 = temp-dreg; // We should try to reevaluate new IR opcode - continue; + //continue; } next = mono_inst_list_next (ins-node, bb-ins_list); @@ -1003,7 +1010,7 @@ ins-sreg2 = temp-dreg; // We should try to reevaluate new IR opcode - continue; + //continue; } next = mono_inst_list_next (ins-node, bb-ins_list); @@ -5861,9 +5868,39 @@ return 0; } +gpointer +mono_arch_get_this_arg_from_call (MonoMethodSignature *sig, gssize *regs, guint8 *code) +{ + unsigned int *pc = (unsigned int *)code; + ALPHA_PRINT g_debug(ALPHA_CHECK: [mono_arch_get_this_arg_from_call] code: %p regs: %p, + pc, regs); + +if (MONO_TYPE_ISSTRUCT (sig-ret)) +return (gpointer)regs [alpha_a1]; +else +return (gpointer)regs [alpha_a0]; +} + +gpointer +mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target) +{ + unsigned int *code, *start; +MonoDomain *domain = mono_domain_get (); +int i; + + ALPHA_PRINT g_debug(ALPHA_CHECK: [mono_arch_get_delegate_invoke_impl]); + +/* FIXME: Support more cases */ +if (MONO_TYPE_ISSTRUCT (sig-ret)) +return NULL; + + return NULL; +} + guint32 mono_arch_get_patch_offset (guint8 *code) { return 3; } + Index: mono/mono/mini/mini-alpha.h === --- mono/mono/mini/mini-alpha.h (revision 95543) +++ mono/mono/mini/mini-alpha.h (working
Re: [Mono-dev] Some strange behavior of optimization options for JIT
Massimiliano Mantione wrote: Hey, you sent this on Christmas :-) On Mon, 2006-12-25 at 19:11 +0300, Sergey Tikhonov wrote: As we see two locals were introduced to hold sum results. In mono_arch_allocate_vars the mono_allocate_stack_slots_full is called to allocate locals and calculate offsets for them. Somehow it doesn't do it: I was just looking at this code for another issue: http://bugzilla.ximian.com/show_bug.cgi?id=80307 When I'll commit the fix for it, would you mind to check if it also solves yours? And if it does not (because yours is really a liveness problem), can you please file a bug? I fixed it lcaly as suggested by Zoltan. It helped. The only problem I see that it always invalidates liveness info (interesting that it happened on alpha and didn't happen on amd64). Sure, I will test your fix. Regards, -- Sergey Tikhonov Head, RD department Solvo Ltd. Saint-Petersburg, Russia http://www.solvo.ru [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Some strange behavior of optimization options for JIT
Sergey Tikhonov wrote: Hello, I am experiencing some strange problems when run mini tests with --optimize=all option. Here is example: method to IR System.Collections.ArrayList:Add (object) converting (in B2: stack: 0) IL_: ldarg.0 converting (in B2: stack: 1) IL_0001: ldfld 0x04000412 converting (in B2: stack: 1) IL_0006: ldlen converting (in B2: stack: 1) IL_0007: conv.i4 converting (in B2: stack: 1) IL_0008: ldarg.0 converting (in B2: stack: 2) IL_0009: ldfld 0x04000411 converting (in B2: stack: 2) IL_000e: bgt IL_0021 converting (in B5: stack: 0) IL_0013: ldarg.0 converting (in B5: stack: 1) IL_0014: ldarg.0 converting (in B5: stack: 2) IL_0015: ldfld 0x04000411 converting (in B5: stack: 2) IL_001a: ldc.i4.1 converting (in B5: stack: 3) IL_001b: add converting (in B5: stack: 2) IL_001c: call 0x06001445 mono_arch_get_inst_for_method: EnsureCapacity ALPHA: Will call Managed method with 1(1) params. RetType: MONO_TYPE_VOID(0x1) ALPHA: Param[0] - simple ALPHA: Param[1] - simple converting (in B4: stack: 0) IL_0021: ldarg.0 converting (in B4: stack: 1) IL_0022: ldfld 0x04000412 Here is IR before optimizations: SSAPRE STARTS PROCESSING METHOD System.Collections.ArrayList:Add (object) BEFORE SSAPRE START CODE BLOCK 3 (nesting 0): (stind.i4 local[2] iconst[0]) (bgt[B6B5] (compare (long_conv_to_i4 (ldlen (ldind.ref (long_add (ldind.i arg[0]) iconst[24] (ldind.i4 (long_add (ldind.i arg[0]) iconst[16] CODE BLOCK 5 (nesting 0): (outarg_reg (add (ldind.i4 (long_add (ldind.i arg[0]) iconst[16])) iconst[1])) (outarg_reg (ldind.i arg[0])) voidcall[EnsureCapacity] br[B4] CODE BLOCK 4 (nesting 0): Here is after optimizations: SSAPRE ENDS PROCESSING METHOD System.Collections.ArrayList:Add (object) remove_block_if_useless System.Collections.ArrayList:Add (object), removed BB6 br removal triggered 5 - 4 BEFORE DECOMPSE START CODE BLOCK 3 (nesting 0): (stind.i4 local[2] iconst[0]) (stind.i local[9] (long_add (ldind.i arg[0]) iconst[16])) (stind.i local[8] (long_add (ldind.i arg[0]) iconst[24])) (bgt[B4B5] (compare (long_conv_to_i4 (ldlen (ldind.ref (ldind.i local[8] (ldind.i4 (ldind.i local[9] CODE BLOCK 5 (nesting 0): (outarg_reg (add (ldind.i4 (ldind.i local[9])) iconst[1])) (outarg_reg (ldind.i arg[0])) voidcall[EnsureCapacity] nop CODE BLOCK 4 (nesting 0): As we see two locals were introduced to hold sum results. In mono_arch_allocate_vars the mono_allocate_stack_slots_full is called to allocate locals and calculate offsets for them. Somehow it doesn't do it: ALPHA: Locals start offset is 16(10) ALPHA: Locals size is 24(18) ALPHA: allocated local 2 to regoffset[0x1c(alpha_r15)] ALPHA: allocated local 3 to regoffset[0x18(alpha_r15)] ALPHA: allocated local 4 to regoffset[0x10(alpha_r15)] ALPHA: allocated local 8 to regoffset[0x20(alpha_r15)] ALPHA: allocated local 9 to regoffset[0x20(alpha_r15)] ALPHA: allocated local 11 to regoffset[0x20(alpha_r15)] ALPHA: reg_save_area_offset at 40(28) ALPHA: args_save_area_offset at 40(28) ALPHA: Stack size is 56(38) DUMP BLOCK 0: DUMP BLOCK 3: (stind.i4 regoffset[0x1c(alpha_r15)] iconst[0]) (stind.i regoffset[0x20(alpha_r15)] (long_add (ldind.i regoffset[0x28(alpha_r15)]) iconst[16])) (stind.i regoffset[0x20(alpha_r15)] (long_add (ldind.i regoffset[0x28(alpha_r15)]) iconst[24])) (bgt[B4B5] (compare (long_conv_to_i4 (ldlen (ldind.ref (ldind.i regoffset[0x20(alpha_r15)] (ldind.i4 (ldind.i regoffset[0x20(alpha_r15)] DUMP BLOCK 5: The local vars 8,9,11 are in the list of local vars, but assigned offsets are the same. And size allocated for locals is less than needed. :( I checked the other arch sources and don't see any magic I have to do. Any hints? I guess it should allocate it. After some investigations I've found that this is SSAPRE optimization that fails. Suprisely it does work on AMD64, although there should not be any arch dependancy. The new temporary registers created by ssapre optimizer don't get correct live info in registry live pass in liveness.c. I can't understand why. Locals 8,9 should live till compare instruction. Here is liveness dump: START 11 START 9 EXPIR 11 C0 R-1 START 8 EXPIR 9 C0 R-1 START 2 0001 00030009 START 3 00030005 00030008 START 4 00030006 00030008 Any hints where to look at? Thank you, -- Sergey Tikhonov Head, RD department Solvo Ltd. Saint-Petersburg, Russia http://www.solvo.ru [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Patch for mono on linux/alpha
Hello Zoltan, Here is set of patches for mono: - Code cleanup - Some hacks to support debugger - updates for linears optimization Thank you, Sergey. [EMAIL PROTECTED] Index: configure.in === --- configure.in (revision 69965) +++ configure.in (working copy) @@ -1623,7 +1623,7 @@ JIT_SUPPORTED=yes jit_wanted=true arch_target=alpha; - CFLAGS=$CFLAGS -mieee + CFLAGS=$CFLAGS -mieee -O0 case $host_os in linux*) LIBC=libc.so.6.1 @@ -1797,7 +1797,7 @@ fi mono_debugger_supported=no -if test x$TARGET = xAMD64 -o x$TARGET = xX86; then +if test x$TARGET = xAMD64 -o x$TARGET = xX86 -o x$TARGET = xALPHA; then if test x$use_included_gc = xyes; then case $host in *-*-*linux*) Index: mono/arch/alpha/alpha-codegen.h === --- mono/arch/alpha/alpha-codegen.h (revision 69965) +++ mono/arch/alpha/alpha-codegen.h (working copy) @@ -562,7 +562,8 @@ #define alpha_cpysn(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x17, 0x021, Rsrc1, Rsrc2, Rdest ) #define alpha_cpyse(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x17, 0x022, Rsrc1, Rsrc2, Rdest ) -#define alpha_trapb(ins) alpha_encode_op(ins, 0x18, 0, 0, 0, 0); +#define alpha_trapb(ins) alpha_encode_mem_fc( ins, 0x18, 0x, 0, 0, 0 ) +#define alpha_mb(ins) alpha_encode_mem_fc( ins, 0x18, 0x4000, 0, 0, 0 ) #endif Index: mono/mini/mini-alpha.h === --- mono/mini/mini-alpha.h (revision 69965) +++ mono/mini/mini-alpha.h (working copy) @@ -64,6 +64,9 @@ guint64 eip; // RA ? or caller PC guint64 rsp; // SP ? caller SP guint64 rgp; // GP + guint64 r14; + guint64 r13; + guint64 r12; }; #define MONO_ARCH_FRAME_ALIGNMENT 8 Index: mono/mini/mini-alpha.c === --- mono/mini/mini-alpha.c (revision 69965) +++ mono/mini/mini-alpha.c (working copy) @@ -1554,7 +1554,7 @@ { CFG_DEBUG(3) g_print(ALPHA: Saved aggregate arg reg %d at offset: %0lx\n, ainfo-reg + j, inst-inst_offset + (8*j)); - alpha_stq(code, ainfo-reg+j, inst-inst_basereg, + alpha_stq(code, (ainfo-reg+j), inst-inst_basereg, (inst-inst_offset + (8*j))); offset += 8; } @@ -1675,9 +1675,10 @@ guint32 mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv) { + MonoInst *ins = cfg-varinfo [vmv-idx]; + /* FIXME: */ CFG_DEBUG(2) ALPHA_DEBUG(mono_arch_regalloc_cost); - MonoInst *ins = cfg-varinfo [vmv-idx]; if (cfg-method-save_lmf) /* The register is already saved */ @@ -1784,11 +1785,11 @@ mono_arch_emit_epilog (MonoCompile *cfg) { MonoMethod *method = cfg-method; - int quad, offset, i; + int offset, i; unsigned int *code; int max_epilog_size = 128; int stack_size = cfg-arch.stack_size; - CallInfo *cinfo; + // CallInfo *cinfo; gint32 lmf_offset = cfg-arch.lmf_offset; CFG_DEBUG(2) ALPHA_DEBUG(mono_arch_emit_epilog); @@ -2365,17 +2366,17 @@ // Shift 32 bit unsigned value right CFG_DEBUG(4) g_print(ALPHA_CHECK: [int_shr_un] dreg=%d, sreg1=%d, sreg2=%d\n, ins-dreg, ins-sreg1, ins-sreg2); - alpha_zap_(code, ins-sreg1, 0xF0, ins-dreg); - alpha_srl(code, ins-dreg, ins-sreg2, ins-dreg); + alpha_zap_(code, ins-sreg1, 0xF0, alpha_at /*ins-dreg*/); + alpha_srl(code, alpha_at /*ins-dreg*/, ins-sreg2, ins-dreg); break; case OP_ISHR_UN_IMM: // Shift 32 bit unassigned value rigth by constant g_assert(alpha_is_imm(ins-inst_imm)); CFG_DEBUG(4) g_print(ALPHA_CHECK: [int_shr_un_imm] dreg=%d, sreg1=%d, const=%ld\n, - ins-dreg, ins-sreg1, ins-inst_imm); - alpha_zap_(code, ins-sreg1, 0xF0, ins-dreg); - alpha_srl_(code, ins-dreg, ins-inst_imm, ins-dreg); +ins-dreg, ins-sreg1, ins-inst_imm); + alpha_zap_(code, ins-sreg1, 0xF0, alpha_at /*ins-dreg*/); + alpha_srl_(code, alpha_at /*ins-dreg*/, ins-inst_imm, ins-dreg); break; case OP_LSHR_UN_IMM: @@ -2872,7 +2873,7 @@ // Valid only for storing 0 // storei1_membase_reg will do the rest - CFG_DEBUG(4) g_printf(ALPHA_CHECK: [storei1_membase_imm(0)] const=%0lx, destbasereg=%d, offset=%0lx\n, + CFG_DEBUG(4) g_print(ALPHA_CHECK: [storei1_membase_imm(0)] const=%0lx, destbasereg=%d, offset=%0lx\n, ins-inst_imm, ins-inst_destbasereg, ins-inst_offset); g_assert(ins-inst_imm == 0); @@ -2912,7 +2913,7 @@ // Now work only for storing 0 // For now storei2_membase_reg will do the work - CFG_DEBUG(4) g_printf(ALPHA_CHECK: [storei2_membase_imm(0)] const=%0lx, destbasereg=%d, offset=%0lx\n, + CFG_DEBUG(4) g_print(ALPHA_CHECK: [storei2_membase_imm(0)] const=%0lx, destbasereg=%d, offset=%0lx\n,
[Mono-dev] Some strange behavior of optimization options for JIT
Hello, I am experiencing some strange problems when run mini tests with --optimize=all option. Here is example: method to IR System.Collections.ArrayList:Add (object) converting (in B2: stack: 0) IL_: ldarg.0 converting (in B2: stack: 1) IL_0001: ldfld 0x04000412 converting (in B2: stack: 1) IL_0006: ldlen converting (in B2: stack: 1) IL_0007: conv.i4 converting (in B2: stack: 1) IL_0008: ldarg.0 converting (in B2: stack: 2) IL_0009: ldfld 0x04000411 converting (in B2: stack: 2) IL_000e: bgt IL_0021 converting (in B5: stack: 0) IL_0013: ldarg.0 converting (in B5: stack: 1) IL_0014: ldarg.0 converting (in B5: stack: 2) IL_0015: ldfld 0x04000411 converting (in B5: stack: 2) IL_001a: ldc.i4.1 converting (in B5: stack: 3) IL_001b: add converting (in B5: stack: 2) IL_001c: call 0x06001445 mono_arch_get_inst_for_method: EnsureCapacity ALPHA: Will call Managed method with 1(1) params. RetType: MONO_TYPE_VOID(0x1) ALPHA: Param[0] - simple ALPHA: Param[1] - simple converting (in B4: stack: 0) IL_0021: ldarg.0 converting (in B4: stack: 1) IL_0022: ldfld 0x04000412 Here is IR before optimizations: SSAPRE STARTS PROCESSING METHOD System.Collections.ArrayList:Add (object) BEFORE SSAPRE START CODE BLOCK 3 (nesting 0): (stind.i4 local[2] iconst[0]) (bgt[B6B5] (compare (long_conv_to_i4 (ldlen (ldind.ref (long_add (ldind.i arg[0]) iconst[24] (ldind.i4 (long_add (ldind.i arg[0]) iconst[16] CODE BLOCK 5 (nesting 0): (outarg_reg (add (ldind.i4 (long_add (ldind.i arg[0]) iconst[16])) iconst[1])) (outarg_reg (ldind.i arg[0])) voidcall[EnsureCapacity] br[B4] CODE BLOCK 4 (nesting 0): Here is after optimizations: SSAPRE ENDS PROCESSING METHOD System.Collections.ArrayList:Add (object) remove_block_if_useless System.Collections.ArrayList:Add (object), removed BB6 br removal triggered 5 - 4 BEFORE DECOMPSE START CODE BLOCK 3 (nesting 0): (stind.i4 local[2] iconst[0]) (stind.i local[9] (long_add (ldind.i arg[0]) iconst[16])) (stind.i local[8] (long_add (ldind.i arg[0]) iconst[24])) (bgt[B4B5] (compare (long_conv_to_i4 (ldlen (ldind.ref (ldind.i local[8] (ldind.i4 (ldind.i local[9] CODE BLOCK 5 (nesting 0): (outarg_reg (add (ldind.i4 (ldind.i local[9])) iconst[1])) (outarg_reg (ldind.i arg[0])) voidcall[EnsureCapacity] nop CODE BLOCK 4 (nesting 0): As we see two locals were introduced to hold sum results. In mono_arch_allocate_vars the mono_allocate_stack_slots_full is called to allocate locals and calculate offsets for them. Somehow it doesn't do it: ALPHA: Locals start offset is 16(10) ALPHA: Locals size is 24(18) ALPHA: allocated local 2 to regoffset[0x1c(alpha_r15)] ALPHA: allocated local 3 to regoffset[0x18(alpha_r15)] ALPHA: allocated local 4 to regoffset[0x10(alpha_r15)] ALPHA: allocated local 8 to regoffset[0x20(alpha_r15)] ALPHA: allocated local 9 to regoffset[0x20(alpha_r15)] ALPHA: allocated local 11 to regoffset[0x20(alpha_r15)] ALPHA: reg_save_area_offset at 40(28) ALPHA: args_save_area_offset at 40(28) ALPHA: Stack size is 56(38) DUMP BLOCK 0: DUMP BLOCK 3: (stind.i4 regoffset[0x1c(alpha_r15)] iconst[0]) (stind.i regoffset[0x20(alpha_r15)] (long_add (ldind.i regoffset[0x28(alpha_r15)]) iconst[16])) (stind.i regoffset[0x20(alpha_r15)] (long_add (ldind.i regoffset[0x28(alpha_r15)]) iconst[24])) (bgt[B4B5] (compare (long_conv_to_i4 (ldlen (ldind.ref (ldind.i regoffset[0x20(alpha_r15)] (ldind.i4 (ldind.i regoffset[0x20(alpha_r15)] DUMP BLOCK 5: The local vars 8,9,11 are in the list of local vars, but assigned offsets are the same. And size allocated for locals is less than needed. :( I checked the other arch sources and don't see any magic I have to do. Any hints? I guess it should allocate it. Thank you, Sergey Tikhonov Head, RD department Solvo Ltd. Saint-Petersburg, Russia http://www.solvo.ru [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Port of mdb to Linux/Alpha
Hello, I started to work on port of mdb to linux/alpha. I implemented some of the callback methods (just to check that it works). For now I am stuck in spawn method. It forks as expected, the child set itself to be traceable and runs mono with assemble to debug. The parent issue read command from pipe created for the child. At that point it waits and doesn't return. Are there any specifics to be known? Is there known minimum set of callback methods for implementation? What data does the read waits? Are the debug method in mono itself shoudl be implemented? (they are in my case) Thank you, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Global register allocator in JIT
Zoltan Varga wrote: Hi, This is perfectly normal, the current burg phase sometimes introduces such extra moves. What is the C#/IL from which this was generated ? Actually, I found the problem. It is common (inssel.brg) that defines reg: CEE_LDIND_REF_REF(OP_REGVAL), reg: CEE_LDIND_I (OP_REGVAL), reg: CEE_LDIND_I4(OP_REGVAL), reg: CEE_LDIND_U4(OP_REGVAL) { MONO_EMIT_UNALU( OP_MOVE ...) } I checked ia64 version and it overrides those insts. The resulted code became better - now global regs are used as source ones. Next step is to use global regs as dest (now it puts result of operation into a local reg and then copy it into the global). The code I am trying to get an optimized version is System_String_memcpy method. Thank you, PS. I got all pinvoke calls working (managed-native, native-managed). :) -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Global register allocator in JIT
Hello, Here is another example I am trying to understand: The IL code is: converting (in B8: stack: 0) IL_0025: ldarg.0 converting (in B8: stack: 1) IL_0026: conv.i converting (in B8: stack: 1) IL_0027: ldc.i4.0 converting (in B8: stack: 2) IL_0028: add converting (in B8: stack: 1) IL_0029: ldarg.1 converting (in B8: stack: 2) IL_002a: conv.i converting (in B8: stack: 2) IL_002b: ldc.i4.0 converting (in B8: stack: 3) IL_002c: add converting (in B8: stack: 2) IL_002d: ldind.u1 converting (in B8: stack: 2) IL_002e: stind.i1 converting (in B8: stack: 0) IL_002f: ldarg.0 converting (in B8: stack: 1) IL_0030: ldc.i4.1 converting (in B8: stack: 2) IL_0031: add converting (in B8: stack: 1) IL_0032: starg.s 0 converting (in B8: stack: 0) IL_0034: ldarg.1 converting (in B8: stack: 1) IL_0035: ldc.i4.1 converting (in B8: stack: 2) IL_0036: add converting (in B8: stack: 1) IL_0037: starg.s 1 converting (in B8: stack: 0) IL_0039: ldarg.2 converting (in B8: stack: 1) IL_003a: ldc.i4.1 converting (in B8: stack: 2) IL_003b: sub converting (in B8: stack: 1) IL_003c: starg.s 2 Converted to: DUMP BLOCK 8: (stind.i1 (long_add (long_conv_to_i (ldind.i regvar[alpha_r12])) iconst[0]) (ldind.u1 (long_add (long_conv_to_i (ldind.i regvar[alpha_r13])) iconst[0]))) (stind.i regvar[alpha_r12] (long_add (ldind.i regvar[alpha_r12]) iconst[1])) (stind.i regvar[alpha_r13] (long_add (ldind.i regvar[alpha_r13]) iconst[1])) (stind.i4 regvar[alpha_r14] (sub (ldind.i4 regvar[alpha_r14]) iconst[1])) The second and third line uses r12 and r13 registers (as wished). LOCAL REGALLOC: BASIC BLOCK: 8 1 move R31 - alpha_r12 2 move R34 - alpha_r13 3 loadu1_membase R33 - R34 4 storei1_membase_reg [R31] - R33 5 add_imm R36 - alpha_r12 6 move alpha_r12 - R36 7 add_imm R38 - alpha_r13 8 move alpha_r13 - R38 9 int_sub_imm R40 - alpha_r14 10 move alpha_r14 - R40 The better code would be: LOCAL REGALLOC: BASIC BLOCK: 8 3 loadu1_membase R33 - alpha_r13 4 storei1_membase_reg [alpha_r12] - R33 5 add_imm alpha_r12 - alpha_r12 7 add_imm alpha_r13- alpha_r13 9 int_sub_imm alpha_r14 - alpha_r14 I tried to defined the following brg rules, but it failed. What did I do wrong? :( stmt: CEE_STIND_I (OP_REGVAR, CEE_ADD (reg, OP_ICONST)) { MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state-left-tree-dreg, state-right-left-reg1, state-right-right-tree-inst_c0); } stmt: CEE_STIND_I (OP_REGVAR, CEE_ADD (OP_REGVAR, OP_ICONST)) { MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state-left-tree-dreg, state-right-left-reg1, state-right-right-tree-inst_c0); } I am afraid that adding more global regs (for now I am just using only 3) would make the code longer and slower. :( Thank you, Sergey. [EMAIL PROTECTED] Solvo Ltd. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Global register allocator in JIT
Zoltan Varga wrote: Hi, To match the example, these should use OP_LADD instead of CEE_ADD. The burg phase has an optimization to avoid useless moves when compiling trees of the form: (stind.i regvar[REG] (TREE)) It is turned on by defining MONO_ARCH_ENABLE_EMIT_STATE_OPT in the mini-ARCH.h file. It is defined for alpha, so I don't know why it is not working there. It does on other architectures. Thank you. The macro was not defined (it was in file, but was not active :) ). I defined it and it helped. The code looks better now, but there are still some issues. I checked generated code for amd64 - here is something interesting (the same method): LABEL BLOCK 12: (stind.i2 (long_add (long_conv_to_i (ldind.i regvar[%r13])) iconst[0]) (ldind.i2 (long_add (long_conv_to_i (ldind.i regvar[%r14])) iconst[0]))) (stind.i regvar[%r13] (long_add (long_conv_to_i (ldind.i regvar[%r13])) iconst[2])) (stind.i regvar[%r14] (long_add (long_conv_to_i (ldind.i regvar[%r14])) iconst[2])) (stind.i4 regvar[%r15] (sub (ldind.i4 regvar[%r15]) iconst[2])) LOCAL REGALLOC: BASIC BLOCK: 12 1 move R16 - %r13 2 move R19 - %r14 3 loadi2_membase R18 - R19 4 storei2_membase_reg [R16] - R18 5 move R21 - %r13 6 add_imm %r13 - R21 clobbers: 1 7 move %r13 - %r13 8 move R23 - %r14 9 add_imm %r14 - R23 clobbers: 1 10 move %r14 - %r14 11 sub_imm %r15 - %r15 clobbers: 1 BB:12 b0: 49 8b c5mov%r13,%rax b3: 49 8b cemov%r14,%rcx b6: 48 0f bf 09 movswq (%rcx),%rcx ba: 66 89 08mov%cx,(%rax) bd: 49 8b c5mov%r13,%rax -- c0: 49 83 c5 02 add$0x2,%r13 c4: 49 8b c6mov%r14,%rax-- c7: 49 83 c6 02 add$0x2,%r14 cb: 49 83 ef 02 sub$0x2,%r15 Thank you for helping me out (I will have more questions :) ) Regards, Sergey. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Patch for mono on Linux/Alpha
Hello Zoltan, Here is patch for mono on Linux/Alpha. The list of changes is: - Fix atomic decrement - Use native long shift insts - Implemented mono_arch_patch_delegate_trampoline method - Started work on using global registers - Use byte/word memory load/store insts if cpu supports it - Code clean up Thank you, Sergey. Index: mono/mono/io-layer/atomic.h === --- mono/mono/io-layer/atomic.h (revision 66543) +++ mono/mono/io-layer/atomic.h (working copy) @@ -869,12 +869,12 @@ __asm__ __volatile__ ( 1: ldl_l %0, %1\n - addl %0, %3, %0\n + subl %0, %3, %0\n mov %0, %2\n stl_c %0, %1\n beq %0, 1b\n : =r (temp), =m (*val), =r (cur) - : Ir (-1), m (*val)); + : Ir (1), m (*val)); return(cur); } Index: mono/mono/mini/cpu-alpha.md === --- mono/mono/mini/cpu-alpha.md (revision 66558) +++ mono/mono/mini/cpu-alpha.md (working copy) @@ -94,9 +94,9 @@ and: dest:i src1:i src2:i len:4 or: dest:i src1:i src2:i len:4 xor: dest:i src1:i src2:i len:4 -shl: dest:i src1:i src2:s len:4 -shr: dest:i src1:i src2:s len:8 -shr.un: dest:i src1:i src2:s len:8 +shl: dest:i src1:i src2:i len:4 +shr: dest:i src1:i src2:i len:4 +shr.un: dest:i src1:i src2:i len:8 neg: dest:i src1:i len:4 not: dest:i src1:i len:4 conv.i1: dest:i src1:i len:12 @@ -244,9 +244,9 @@ long_div_un: dest:a src1:a src2:i len:16 clob:d long_rem: dest:d src1:a src2:i len:16 clob:a long_rem_un: dest:d src1:a src2:i len:16 clob:a -long_shl: dest:i src1:i src2:s clob:1 len:31 -long_shr: dest:i src1:i src2:s len:4 -long_shr_un: dest:i src1:i src2:s len:4 +long_shl: dest:i src1:i src2:i len:4 +long_shr: dest:i src1:i src2:i len:4 +long_shr_un: dest:i src1:i src2:i len:4 long_conv_to_r4: dest:f src1:i len:20 long_conv_to_r8: dest:f src1:i len:20 long_conv_to_ovf_i: dest:i src1:i src2:i len:40 @@ -255,7 +255,7 @@ long_conv_to_r_un: dest:f src1:i src2:i len:48 long_shr_imm: dest:i src1:i len:4 long_shr_un_imm: dest:i src1:i len:4 -long_shl_imm: dest:i src1:i clob:1 len:11 +long_shl_imm: dest:i src1:i len:4 float_beq: len:4 float_bne_un: len:12 float_blt: len:4 @@ -378,9 +378,9 @@ int_and: dest:i src1:i src2:i len:4 int_or: dest:i src1:i src2:i len:4 int_xor: dest:i src1:i src2:i len:4 -int_shl: dest:i src1:i src2:s len:4 -int_shr: dest:i src1:i src2:s len:8 -int_shr_un: dest:i src1:i src2:s len:8 +int_shl: dest:i src1:i src2:i len:4 +int_shr: dest:i src1:i src2:i len:8 +int_shr_un: dest:i src1:i src2:i len:8 int_adc: dest:i src1:i src2:i clob:1 len:64 int_adc_imm: dest:i src1:i clob:1 len:64 int_sbb: dest:i src1:i src2:i clob:1 len:64 Index: mono/mono/mini/tramp-alpha.c === --- mono/mono/mini/tramp-alpha.c(revision 66558) +++ mono/mono/mini/tramp-alpha.c(working copy) @@ -510,12 +510,68 @@ } +/* +** This method is called after delegate method is compiled. +** We need to patch call site to call compiled method directly +** (not via trampoline stub) +** Determine address to patch using fp reg +** +*/ void mono_arch_patch_delegate_trampoline (guint8 *code, guint8 *tramp, gssize *regs, guint8 *addr) { + unsigned int *pcode = (unsigned int *)code; + int reg; + short fp_disp, obj_disp; + unsigned long *pobj, obj; + ALPHA_DEBUG(mono_arch_patch_delegate_trampoline); + + // The call signature for now is + // -4 - ldq v0,24(fp) + // -3 - ldq v0,40(v0) + // -2 - mov v0,t12 + // -1 - jsr ra,(t12),0x200041476e4 + // 0 - ldahgp,0(ra) + if (((pcode[-4] 0xFF00) == 0xA400) + ((pcode[-3] 0xFF00) == 0xA400) + ((pcode[-2] 0xFF00FF00) == 0x47000400) + ((pcode[-1] 0x) == 0x6B5B)) +{ + fp_disp = (pcode[-4] 0x); + obj_disp = (pcode[-3] 0x); + + pobj = regs[15] + fp_disp; + obj = *pobj; + reg = 0; +} + else +// The non-optimized call signature for now is +// -5 - ldq v0,24(fp) +// -4 - mov v0,v0 +// -3 - ldq v0,40(v0) +// -2 - mov v0,t12 +// -1 - jsr ra,(t12),0x200041476e4 +// 0 - ldahgp,0(ra) +if (((pcode[-5] 0xFF00) == 0xA400) + ((pcode[-4] 0xFF00FF00) == 0x47000400) + ((pcode[-3] 0xFF00) == 0xA400) + ((pcode[-2] 0xFF00FF00) == 0x47000400) + ((pcode[-1] 0x) == 0x6B5B)) + { + fp_disp = (pcode[-5] 0x); + obj_disp = (pcode[-3] 0x); + + pobj = regs[15] + fp_disp; + obj = *pobj; + reg = 0; + } +else + g_assert_not_reached (); + + *((gpointer*)(obj + obj_disp)) = addr; } void Index: mono/mono/mini/inssel-alpha.brg
[Mono-dev] Global register allocator in JIT
Hello, I am trying to make global register allocator to work on Alpha mono port. It started to use dedicated global registers, but I could not get an idea how it supposed to work. For example: DUMP BLOCK 2: (beq[B3B4] (compare (and (or (long_conv_to_i4 (ldind.i regvar[alpha_r12])) (long_conv_to_i4 (ldind.i regvar[alpha_r13]))) iconst[3]) iconst[0])) uses alpha_r12 and alpha_r13 registers that hold args passed to a method (so far good). But this code is translated to: LOCAL REGALLOC: BASIC BLOCK: 2 1 move R34 - alpha_r12 2 conv.i4 R33 - R34 3 move R36 - alpha_r13 4 conv.i4 R35 - R36 5 int_or R32 - R33 R35 6 int_and_imm R31 - R32 7 alpha_cmp_imm_eq R31 8 int_bne_un Now it start to use local registers to do conv.i4 conversion. Why it can use allocated global regs as source regs for conv opcode? Should peephole pass to handle this? (but it would get complex :( ) How it should work? Thank you, Sergey. [EMAIL PROTECTED] Solvo Ltd. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Patch for mono on Linux/Alpha
Hello Zoltan, Here is another patch for mono on Linux/Alpha. Changes are: - Implemented passing of valuetypes in registers (taken from ia64 version) as requred by ABI (invoking of native methods works, invoking of managed methods from native code - fails) - Enable inline optimization for arch - Implemented generics handling - Code cleanup Now mono on Linux/Alpha builds libraries for both profiles (1.1, 2.0). I was able to build gtk-sharp/gtk-sharp2 RPM packages and run sample programs from them. Suprisely, they worked. :) Thank you, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] Index: mono/mono/mini/mini-alpha.c === --- mono/mono/mini/mini-alpha.c (revision 65696) +++ mono/mono/mini/mini-alpha.c (working copy) @@ -34,7 +34,14 @@ insert_after_ins (bb, last_ins, (dest)); \ } while (0) +#define NEW_ICONST(cfg,dest,val) do { \ +(dest) = mono_mempool_alloc0 ((cfg)-mempool, sizeof (MonoInst)); \ +(dest)-opcode = OP_ICONST; \ +(dest)-inst_c0 = (val); \ +(dest)-type = STACK_I4; \ + } while (0) + #undef DEBUG #define DEBUG(a) if (cfg-verbose_level 1) a @@ -95,24 +102,23 @@ typedef enum { ArgInIReg, -ArgInFloatSSEReg, -ArgInDoubleSSEReg, +ArgInFloatReg, +ArgInDoubleReg, ArgOnStack, -ArgValuetypeInReg, -//ArgOnFloatFpStack, -//ArgOnDoubleFpStack, + ArgValuetypeInReg, // ?? + ArgAggregate, ArgNone } ArgStorage; typedef struct { - gint16 offset; - gint8 reg; - ArgStorage storage; + gint16 offset; + gint8 reg; + ArgStorage storage; - /* Only if storage == ArgValuetypeInReg */ - ArgStorage pair_storage [2]; - gint8 pair_regs [2]; + /* Only if storage == ArgAggregate */ + int nregs, nslots; + //AggregateType atype; // So far use only AggregateNormal } ArgInfo; typedef struct { @@ -180,9 +186,10 @@ { /* A double register */ if (is_double) - ainfo-storage = ArgInDoubleSSEReg; + ainfo-storage = ArgInDoubleReg; else - ainfo-storage = ArgInFloatSSEReg; + ainfo-storage = ArgInFloatReg; + ainfo-reg = fparam_regs [*gr]; (*gr) += 1; } @@ -207,7 +214,7 @@ else size = mono_type_stack_size (klass-byval_arg, NULL); - if (!sig-pinvoke || (size == 0)) { + if (!sig-pinvoke || (size == 0) || is_return) { /* Allways pass in memory */ ainfo-offset = *stack_size; *stack_size += ALIGN_TO (size, 8); @@ -216,18 +223,40 @@ return; } -info = mono_marshal_load_type_info (klass); -g_assert (info); -if (info-native_size/* 16*/) { -ainfo-offset = *stack_size; -*stack_size += ALIGN_TO (info-native_size, 8); -ainfo-storage = ArgOnStack; + info = mono_marshal_load_type_info (klass); + g_assert (info); -return; -} + ainfo-storage = ArgAggregate; + //ainfo-atype = AggregateNormal; +#if 0 + /* This also handles returning of TypedByRef used by some icalls */ + if (is_return) { +if (size = 32) { + ainfo-reg = IA64_R8; + ainfo-nregs = (size + 7) / 8; + ainfo-nslots = ainfo-nregs; + return; +} +NOT_IMPLEMENTED; + } +#endif - NOT_IMPLEMENTED(add_valuetype: more); + ainfo-reg = param_regs [*gr]; + ainfo-offset = *stack_size; + ainfo-nslots = (size + 7) / 8; + + if (((*gr) + ainfo-nslots) = 6) { +/* Fits entirely in registers */ +ainfo-nregs = ainfo-nslots; +(*gr) += ainfo-nregs; +return; + } + + ainfo-nregs = 6 - (*gr); + (*gr) = 6; + (*stack_size) += (ainfo-nslots - ainfo-nregs) * 8; + } // This function is called from mono_arch_call_opcode and @@ -237,7 +266,7 @@ // that will be used in calls static void add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, MonoInst *arg, - ArgStorage storage, int reg, MonoInst *tree) + ArgStorage storage, int reg, MonoInst *tree) { switch (storage) { @@ -248,14 +277,14 @@ arg-unused = reg; call-used_iregs |= 1 reg; break; -case ArgInFloatSSEReg: +case ArgInFloatReg: arg-opcode = OP_OUTARG_FREG; arg-inst_left = tree; arg-inst_right = (MonoInst*)call; arg-unused = reg; call-used_fregs |= 1 reg; break; -case ArgInDoubleSSEReg: +case ArgInDoubleReg: arg-opcode = OP_OUTARG_FREG; arg-inst_left = tree; arg-inst_right = (MonoInst*)call; @@ -1344,8 +1373,8 @@ } //} break; - case ArgInDoubleSSEReg: - case ArgInFloatSSEReg: + case ArgInDoubleReg: + case ArgInFloatReg: // We need to save all used af0-af5 params
[Mono-dev] Possible bug in mini-ia64.c
Hello Zoltan, Could you take a look at mono_arch_call_opcode function in mini-ia64.c. I copied the logic of passing value types in registers from ia64 version and it failed for me in one case. We have loop there we analize arguments to pass. We use variable i as index. If ainfo-storage = ArgAggregate it seems that we use the same i variable to loop through allocated nregs for value type. This is where I went into infinitive loop. I changed nested loop to use another variable (j) and it started to work. Am I right? Thank you, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, Here is another set of patches for mono on Linux/Alpha. What is changed: - Reworked passing of arguments on stack - now it is more close to ABI (and same as gcc) and safe from stack allocation leaks - New argument passing schema would allow to start pass valuetypes in registers (as native methods expect) - Fixed start_handler/endfinally/endfilter - not to modify stack pointer - Added implemetation of lconv_to_i/u4 - Some opcode implemetation and fixes - Fixed strtod for Alpha - Added native opcodes patch missed from previous patchset With all of that I was able to build mcs compiler and using it build all assembles in mcs directory. :) So, now it could be considered that the mono is supported on Linux/Alpha as betta version. :) Number of failed tests in mono/tests down to 7. Most of the pinvokes with complex parameters, vararg and one thread tests. Regards, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] Index: mono/mono/mini/exceptions-alpha.c === --- mono/mono/mini/exceptions-alpha.c (revision 65271) +++ mono/mono/mini/exceptions-alpha.c (working copy) @@ -310,6 +310,7 @@ /* Exception is in a0 already */ alpha_mov1(code, alpha_ra, alpha_a1); // Return address alpha_mov1(code, alpha_sp, alpha_a2); // Stack pointer + if (rethrow) alpha_lda(code, alpha_a3, alpha_zero, 1); else @@ -746,6 +747,7 @@ { static guint8 *start; static int inited = 0; + unsigned int *code; if (inited) return start; @@ -754,6 +756,10 @@ //get_throw_exception_generic (start, SZ_THROW, TRUE, FALSE); inited = 1; + code = (unsigned int *)start; + + alpha_call_pal(code, 0x80); + return start; } /*= End of Function */ @@ -912,9 +918,12 @@ /* Some how we should find size of frame. One way: read 3rd instruction (alpha_lda(alpha_sp, alpha_sp, -stack_size )) and extract stack_size from there + read 4th and 5th insts to get offsets to saved RA FP */ unsigned int *code = (unsigned int *)ji-code_start; short stack_size = -((short)(code[2] 0x)); + short ra_off = code[3] 0x; + short fp_off = code[4] 0x; /* Restore stack - value of FP reg + stack_size */ new_ctx-uc_mcontext.sc_regs[alpha_sp] = @@ -923,11 +932,11 @@ /* we substract 1, so that the IP points into the call instruction */ /* restore PC - @FP + 0 */ new_ctx-uc_mcontext.sc_pc = - *((guint64 *)ctx-uc_mcontext.sc_regs[alpha_r15]); + *((guint64 *)(ctx-uc_mcontext.sc_regs[alpha_r15] + ra_off)); /* Restore FP reg - @FP + 8 */ new_ctx-uc_mcontext.sc_regs[alpha_r15] = - *((guint64 *)(ctx-uc_mcontext.sc_regs[alpha_r15] + 8)); + *((guint64 *)(ctx-uc_mcontext.sc_regs[alpha_r15] + fp_off)); /* Restore GP - read two insts that restore GP from sc_pc and */ /* do the same. Use sc_pc as RA */ @@ -945,7 +954,10 @@ } } +#if 0 /* Pop arguments off the stack */ + // No poping args off stack on Alpha + // We use fixed place { MonoJitArgumentInfo *arg_info = g_newa (MonoJitArgumentInfo, @@ -957,7 +969,7 @@ arg_info); new_ctx-uc_mcontext.sc_regs[alpha_sp] += stack_to_pop; } - +#endif return ji; } else if (*lmf) Index: mono/mono/mini/cpu-alpha.md === --- mono/mono/mini/cpu-alpha.md (revision 65271) +++ mono/mono/mini/cpu-alpha.md (working copy) @@ -57,7 +57,7 @@ arg: arglist: break: len:4 -jmp: len:4 +jmp: len:48 br: len:4 beq: len:4 bge: len:4 @@ -99,8 +99,8 @@ shr.un: dest:i src1:i src2:s len:8 neg: dest:i src1:i len:4 not: dest:i src1:i len:4 -conv.i1: dest:i src1:i len:4 -conv.i2: dest:i src1:i len:4 +conv.i1: dest:i src1:i len:12 +conv.i2: dest:i src1:i len:12 conv.i4: dest:i src1:i len:4 conv.i8: dest:i src1:i len:4 conv.r4: dest:f src1:i len:20 @@ -126,7 +126,7 @@ cgt.un: dest:c len:8 clt: dest:c len:8 clt.un: dest:c len:8 -localloc: dest:i src1:i len:84 +localloc: dest:i src1:i len:20 compare: src1:i src2:i len:4 lcompare: src1:i src2:i len:4 icompare: src1:i src2:i len:4 @@ -304,7 +304,7 @@ call_handler: len:4 start_handler: len:96 endfinally: len:96 -op_endfilter: len:96 +op_endfilter: src1:i len:96 aot_const: dest:i len:10 # x86_test_null: src1:i len:5 # x86_compare_membase_reg: src1:b src2:i len:9 Index: mono/mono/mini/tramp-alpha.c === --- mono/mono/mini/tramp-alpha.c(revision 65271) +++ mono/mono/mini/tramp-alpha.c(working copy) @@ -625,3 +625,25 @@ g_assert_not_reached (); } +/* + * This method is only called when
Re: [Mono-dev] Building Mono on Linux/Alpha
Massimiliano Mantione wrote: On Thu, 2006-09-07 at 12:29 -0400, Miguel de Icaza wrote: Hello, I have some questions about mono_local_regalloc. Is it possible to tell its logic right now not to reuse the same physical register in the same instruction? Alpha has a lot of registers and experience some penalty if the same register is used in the same or next instruction when results of previous instruction are not needed for next. For example: This is a design consideration that might be worth including in the next register allocator. Interesting... This also looks relatively easy to do, I will take it into account. I say relatively easy because the new regalloc, unlike the previous one, is able (and willing) to split liveness ranges at each definition, so that in practice each definition of the same vreg could go into a different hard register if necessary (of course if this does not introduce too many useless resolution moves at BB boundaries). Just to be sure I got it right: when there is more than one free register to choose from, all else being equal, the regalloc should favor registers that have been freed earlier instead of later. Handling free registers like a FIFO queue during the linear allocation should be enough to do this trick: at BB boundaries the heuristic could fail, but elsewhere it should do exactly what Sergey asked. Of course, if a special/particular register is needed, the regalloc can walk the queue and pick what it needs, this is just to get you the idea. Comments? Well, after reading specs for alpha,x86/amd64,ia64 cpus. I see that that only issue that could be avoided by using new register is WAW (write-after-write) problem. Current code pattern has a lot of instructions like this: load from memory to temp reg save temp reg to memory load from memory to temp reg save temp reg to memory The second load/save could not be issued at the same time (by current out of order cpus), because it has to use the same temp register as the first load/store. I think your solution should work. Is there place in current design where instruction scheduling at IR level could be implemented? (before local regalloc assignment) Just wandering. :) Regards, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello, I have some questions about mono_local_regalloc. Is it possible to tell its logic right now not to reuse the same physical register in the same instruction? Alpha has a lot of registers and experience some penalty if the same register is used in the same or next instruction when results of previous instruction are not needed for next. For example: 1. op_loadmembase dest_reg1, offset1(basereg) 2. op_storemembase src_reg (= dest_reg1), offset2(basereg) 3. op_loadmembase dest_reg1, offset3(basereg) 4. op_storemembase src_reg (= dest_reg1), offset4(basereg) I would like for 3rd and 4th instruction the different temp (dest_reg1/src_reg1) to be used. The better schedulling will be if the instructions are arranged in following sequence - 1,3,2,4, but I am not asking for that. :) Another question: is the reg: OP_LCONV_TO_I4 (reg) operation correctly expected to be implemented by OP_LSHR_IMM (long right shift) opcode? The next unsigned version uses OP_ISHR_UN_IMM (integer shift). Thank you, PS: My failed tests down to 7 and most of them pinvokes with valuetypes (pinvoke with simple types work). -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, The local register allocator can't do instruction scheduling. I think the Yes, I understand that. I was not expecting register allocator to do instruction scheduling. :) My first question was - is there way to ask it to use different physical registers for next instruction or reserve it for next n (where in n - configuriable) instructions. In my example it would not use the same register (from 2nd instruction) for 3rd instuction. As far as I recall it is called read/write dependency and if it was defferent register alpha would schedule the 3rd instruction with the 2nd at the same time. I think it might be true for other arches too. This is just a thought. OP_LCONV_TO_I4 rule is wrong, it should use OP_ISHR_IMM. For some reason it seems to work on the existing 64 bit ports. I guess this is because the next instructions is one of store to memory or move to another register as 32bit integer. I stepped on it because alpha doesn't have 32bit compare and my not-negative 64 int wasn't converted and long compare failed. Regards, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, Well, kind of good news for mono on Linux/Alpha. With small hack to mcs source code I was able to build mcs compiler by modified mcs from sources on Linux/Alpha. :) Still need to understand why it fails at first place. Regards, Sergey. [EMAIL PROTECTED] Solvo Ltd. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, Hi, The best approach, as I said previously, is to make sure all the tests (except perhaps the pinvoke/marshalling tests) run under mono/tests. Since these tests are much simpler than mcs, it is much easier to track down the possible problems. I am trying to understand why invoke.cs test fails. The Test1 method is called but ss parameter contains wrong data (ss.a = ss.b = true). If the Test1 method if called directly (not by invoke) the parameter has right values. What should I look at? Is there some kind casting exists from array of objects to SimpleStruct? Some box/unbox methods for parameters? Thank you, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, The best approach, as I said previously, is to make sure all the tests (except perhaps the pinvoke/marshalling tests) run under mono/tests. Since these tests are much simpler than mcs, it is much easier to track down the possible problems. Ok, thank you for advice. I checked the mono/tests and see that there are more tests than in regression testsuite I downloaded from the site (it is said they are old). I will try them out. Playing with mcs I got into alpha-specific problem. In my current aproach working with consts and method addresses requires that the size of generated code should be less than 32kb. The mcs.exe has yyparse method that was translated into 160kb size native code and aborted on internal assertions. :( I would have to find a solution for that too. Regards, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, Well, all tests passed (except one in basic-float with precision). The Hello world program works. :) The mcs.exe still fails. :) So far I'am trying to understand why the following test fails: string af = string.Format({0}, 1); Console.WriteLine(af); it outputs - 539802584 (I know it might be some kind of address). There is one thing that I couldn't find out. The mono_arch_get_vcall_slot_addr function for amd64 checks for 4 cases, but I've found just one - which loads method address from this and calls it. What other cases I should check for? Are there tests that could show it? Thank you, Sergey. [EMAIL PROTECTED] Solvo Ltd. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, Do you mean all tests pass inside mono/tests as well ? Well. :) Not all of them. I downloaded binaries for regression tests from the site and played with them. I haven't tested all of them, but the ones I tried worked. Ok, I guess I am trying to get it working too fast. :) btw, I've just almost got mcs.exe telling that I supplied no files (found stupid bug in opcode generation), but it got into format problem and thrown an exception. As for get_vcall_slot_addr, the amd64 version is complex because the amd64 backend generates many types of call sequences. It needs to handle the machine code generated for the CALL_REG and CALL_MEMBASE opcodes. Ok. Alpha does function call only to an address loaded into a register, so I guess it might be really just one case for alpha. As for string.format (), it is a pretty complex method, try looking at its source code and convert it into a self contained testcase, then try to simplify it until you find the root of the problem. Ok, I will. I just hoped that there were such test cases. :) Thank you, Sergey. [EMAIL PROTECTED] Solvo Ltd. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Sergey Tikhonov wrote: Zoltan Varga wrote: Yes, it doesn't work because they are not implemented. The logic is the following: get_vcall_slot_addr () should determine whenever the call which called the trampoline is a virtual call, and if it is, then Ok. I was comparing different call signatures and it seems that I would have to mark virtual calls some how (like ia64 does in one case), but I will look again. Apparently, virtual call in test_44_unbox_trampoline o.GetHashCode (); is made by using call_membase opcode (I added some addition native codes for OP_VCALL_MEMBASE, but it hasn't been called.) So, I guess get_vcall_slot_addr () some how should determine virtual call only by call signature. :( Am I right? I did implement get_vcall_slot_addr() get_unbox_trampoline() and now test_44_unbox trampoline is passed (even whole TestDriver started to work. :) Now it does all preparation work and starts to call tests. Wow. :) Regards, Sergey. [EMAIL PROTECTED] Solvo Ltd. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, I am trying to understand why test_44_unbox_trampoline (objects.cs) fails. I could not figure out the logic. :( Could you shed some lights? I guess mono_arch_get_vcall_slot_addr and mono_arch_get_unbox_trampoline should be implemented. Thank you, Sergey. [EMAIL PROTECTED] Solvo Ltd. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Yes, it doesn't work because they are not implemented. The logic is the following: get_vcall_slot_addr () should determine whenever the call which called the trampoline is a virtual call, and if it is, then Ok. I was comparing different call signatures and it seems that I would have to mark virtual calls some how (like ia64 does in one case), but I will look again. return the address of the vtable slot used in the call. get_unbox_trampoline () should return a trampoline which increments the first argument of the method by sizeof (MonoObject), then jumps to the address specified. Thank you very much. Regards, Sergey. [EMAIL PROTECTED] Solvo Ltd. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, Hi, I have a question: Alpha arch doesn't have unassigned compare for floats, but IR seems to require it. What would be the best place to implement taking abs values for arguments to compare and do comparition? I was thinking of using inssel-alpha.brg file to add instruction like stmt: OP_COND_BRANCH (OP_COMPARE(freg, freg)) { ... } (I found usage like this in inssel-arm.brg) to implement abs of fregs and do compare, but I read documentation that this would limit optimization and register allocation logic. I don't know how that would limit optimization, so I think it is fine for now. Another thing - Alpha doesn't have special flag register to hold comparition result and uses some of common registers. Right now I am using one predefined register, but this limit its usage for other ops. I would like to use local register allocation to allocate register to hold compare results and use it in conditional branch instruction. This is not currently possible, ia64 has the same problem and uses a dedicated predicate register. Ok, I was able to implement float compare (including unordered compare) in brg file. It really simplified things. Almost all basic-float tests passed. I have a problem with handling of exceptions (divide by zero exception to be exact). In my current implementation the CEE_DIV opcode uses mono_idiv function which does actual division. This method is called without wrapper function (I guess this is because it is registered as opcode_emulation) and it doesn't have flag save_lmf set. So I don't save LMF for it and couldn't find exception handler. :( Do I understand the current logic with unmanaged opcode emulation functions correctly? Do I need to implement div opcode? (yes I guess I need, but I was thinking to do it later) Thank you, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, The code in mini.c is incorrect, _idiv and its friends should be registered with no_throw set to FALSE, instead of TRUE. I will fix it in a minute. Thank you. Now it works as expected. :) Regards, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, The patch is now in SVN. Thank you. There were other patches to common files that haven't got to SVN yet (mono-linux-alpha2.patch). I have a question: Alpha arch doesn't have unassigned compare for floats, but IR seems to require it. What would be the best place to implement taking abs values for arguments to compare and do comparition? I was thinking of using inssel-alpha.brg file to add instruction like stmt: OP_COND_BRANCH (OP_COMPARE(freg, freg)) { ... } (I found usage like this in inssel-arm.brg) to implement abs of fregs and do compare, but I read documentation that this would limit optimization and register allocation logic. Another thing - Alpha doesn't have special flag register to hold comparition result and uses some of common registers. Right now I am using one predefined register, but this limit its usage for other ops. I would like to use local register allocation to allocate register to hold compare results and use it in conditional branch instruction. Thank you, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, Here is another set of patches for common files. Please, review. Thank you, Sergey. [EMAIL PROTECTED] --- ./mono/mono/mini/mini-arch.h.old 2006-07-10 18:54:50.0 +0400 +++ ./mono/mono/mini/mini-arch.h 2006-07-11 22:14:59.0 +0400 @@ -19,6 +19,8 @@ #include mini-ia64.h #elif defined(__arm__) #include mini-arm.h +#elif defined(__alpha__) +#include mini-alpha.h #else #error add arch specific include file in mini-arch.h #endif --- ./mono/mono/mini/Makefile.am.old 2006-07-10 18:54:51.0 +0400 +++ ./mono/mono/mini/Makefile.am 2006-07-11 22:44:16.0 +0400 @@ -167,6 +167,14 @@ mini-codegen.c \ mini-trampolines.c +alpha_sources = \ + mini-alpha.c \ + mini-alpha.h \ + exceptions-alpha.c \ + tramp-alpha.c \ + mini-codegen.c \ + mini-trampolines.c + common_sources = \ mini.c \ mini.h \ @@ -302,6 +310,14 @@ arch_built = cpu-ia64.h endif +if ALPHA +arch_sources = \ + $(alpha_sources) + +arch_BURGSRC = $(srcdir)/inssel-long.brg $(srcdir)/inssel-alpha.brg +arch_built = cpu-alpha.h +endif + libmono_la_SOURCES = $(common_sources) $(arch_sources) nodist_libmono_la_SOURCES = inssel.c inssel.h @@ -345,6 +361,7 @@ cpu-s390.h: cpu-s390.md cpu-s390x.h: cpu-s390x.md cpu-ia64.h: cpu-ia64.md +cpu-alpha.h: cpu-alpha.md ## Gross hack. Making 'genmdesc' a host binary takes more effort $(arch_built): @@ -377,6 +394,9 @@ cpu-ia64.h: cpu-ia64.md genmdesc$(EXEEXT) ./genmdesc $(srcdir)/cpu-ia64.md cpu-ia64.h ia64_desc +cpu-alpha.h: cpu-alpha.md genmdesc$(EXEEXT) + ./genmdesc $(srcdir)/cpu-alpha.md cpu-alpha.h alpha_desc + endif !CROSS_COMPILING inssel.c inssel.h: $(BURGSRC) @@ -446,4 +466,5 @@ $(sparc_sources) inssel-sparc.brg cpu-sparc.md \ $(s390_sources) inssel-s390.brg cpu-s390.md \ $(s390x_sources) inssel-s390x.brg cpu-s390x.md \ - $(ia64_sources) inssel-ia64.brg cpu-ia64.md + $(ia64_sources) inssel-ia64.brg cpu-ia64.md \ + $(alpha_sources) inssel-alpha.brg cpu-alpha.md --- ./mono/mono/mini/mini-ops.h.old 2006-07-10 18:54:50.0 +0400 +++ ./mono/mono/mini/mini-ops.h 2006-07-11 22:49:04.0 +0400 @@ -720,3 +720,19 @@ MINI_OP(OP_IA64_FETCHADD4_IMM, ia64_fetchadd4_imm) MINI_OP(OP_IA64_FETCHADD8_IMM, ia64_fetchadd8_imm) #endif + +#if defined(__alpha__) +MINI_OP(OP_ALPHA_CMP_EQ, alpha_cmp_eq) +MINI_OP(OP_ALPHA_CMP_IMM_EQ, alpha_cmp_imm_eq) +MINI_OP(OP_ALPHA_CMP_ULT, alpha_cmp_ult) +MINI_OP(OP_ALPHA_CMP_IMM_ULT, alpha_cmp_imm_ult) +MINI_OP(OP_ALPHA_CMP_ULE, alpha_cmp_ule) +MINI_OP(OP_ALPHA_CMP_IMM_ULE, alpha_cmp_imm_ule) +MINI_OP(OP_ALPHA_CMP_LT, alpha_cmp_lt) +MINI_OP(OP_ALPHA_CMP_IMM_LT, alpha_cmp_imm_lt) +MINI_OP(OP_ALPHA_CMP_LE, alpha_cmp_le) +MINI_OP(OP_ALPHA_CMP_IMM_LE, alpha_cmp_imm_le) + +MINI_OP(OP_ALPHA_CMPT_EQ, alpha_cmpt_eq) +#endif + --- ./mono/mono/mini/mini-codegen.c.old 2006-07-10 18:54:50.0 +0400 +++ ./mono/mono/mini/mini-codegen.c 2006-07-11 23:06:55.0 +0400 @@ -42,6 +42,9 @@ #elif defined(__s390__) const char * const s390_cpu_desc [OP_LAST]; static const char*const * ins_spec = s390_cpu_desc; +#elif defined(__alpha__) +const char * const alpha_desc [OP_LAST]; +static const char*const * ins_spec = alpha_desc; #else #error Not implemented #endif ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Miguel de Icaza wrote: Hello, Here is another set of patches for common files. Please, review. The patches look fine, but it seems like some of the new files are missing (mini-alpha.c) I am going to send them later. I guess there will be some suggestions about them. The previous patches are trivial and should not affect other arches. :) Thank you, Sergey. [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, Here are few patches for mono to be able correctly configure and compile on Linux/Alpha. Please, review. I switched from version 1.1.13 to svn version recently and had some problems with configure and building process. I will send all other mono alpha specific patches later. Thank you, Sergey. [EMAIL PROTECTED] --- ./mono/configure.in.old 2006-07-10 18:57:08.0 +0400 +++ ./mono/configure.in 2006-07-10 23:14:06.0 +0400 @@ -1581,9 +1581,8 @@ alpha*-*-linux* | alpha*-*-osf*) TARGET=ALPHA; ACCESS_UNALIGNED=no - JIT_SUPPORTED=no - INTERP_SUPPORTED=yes - interp_wanted=true + JIT_SUPPORTED=yes + jit_wanted=true arch_target=alpha; case $host_os in linux*) --- ./mono/libgc/configure.in.old 2006-07-10 18:51:15.0 +0400 +++ ./mono/libgc/configure.in 2006-07-10 22:47:34.0 +0400 @@ -77,7 +77,7 @@ THREADS=posix THREADDLLIBS=-lpthread case $host in - x86-*-linux* | ia64-*-linux* | i386-*-linux* | i486-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha-*-linux* | s390*-*-linux* | sparc*-*-linux* | powerpc-*-linux*) + x86-*-linux* | ia64-*-linux* | i386-*-linux* | i486-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha*-*-linux* | s390*-*-linux* | sparc*-*-linux* | powerpc-*-linux*) AC_DEFINE(GC_LINUX_THREADS) AC_DEFINE(_REENTRANT) if test ${enable_parallel_mark} = yes; then --- ./mono/mono/arch/alpha/alpha-codegen.h.old 2006-07-10 18:55:43.0 +0400 +++ ./mono/mono/arch/alpha/alpha-codegen.h 2006-05-04 00:35:59.0 +0400 @@ -160,7 +160,6 @@ #define __alpha_int_32 unsigned int - /***/ #define AXP_OFF26_MASK 0x03ff #define AXP_OFF21_MASK 0x01f @@ -210,7 +209,7 @@ ((func AXP_OFF7_MASK) AXP_REGSIZE) #define alpha_op_literal( lit ) \ - ((lit AXP_OFF7_MASK) AXP_LIT_SHIFT) + ((lit AXP_OFF8_MASK) AXP_LIT_SHIFT) #define alpha_mem_br_func( func, hint ) \ (((func AXP_OFF2_MASK ) AXP_MEM_BR_SHIFT ) | (hintAXP_OFF14_MASK)) @@ -236,48 +235,56 @@ #define alpha_encode_palcall( ins, op, func ) \ - *((__alpha_int_32*)(ins))++ = ( 0 |\ - alpha_opcode( op ) | ( func AXP_OFF26_MASK )) + *((__alpha_int_32*)(ins)) = ( 0 |\ + alpha_opcode( op ) | ( func AXP_OFF26_MASK )),\ + ((__alpha_int_32*)(ins))++ #define alpha_encode_mem( ins, op, Rdest, Rsrc, offset ) \ - *((__alpha_int_32*)(ins))++ = ( 0 |\ + *((__alpha_int_32*)(ins)) = ( 0 |\ alpha_opcode( op ) | alpha_reg_a( Rdest ) | \ - alpha_reg_b( Rsrc ) | (offset AXP_OFF16_MASK )) + alpha_reg_b( Rsrc ) | (offset AXP_OFF16_MASK )),\ + ((__alpha_int_32*)(ins))++ #define alpha_encode_mem_fc( ins, op, func, Rdest, Rsrc, offset ) \ - *((__alpha_int_32*)(ins))++ = ( 0 |\ + *((__alpha_int_32*)(ins)) = ( 0 |\ alpha_opcode( op ) | alpha_reg_a( Rdest ) | \ - alpha_reg_b( Rsrc ) | alpha_mem_fc_func( func )) + alpha_reg_b( Rsrc ) | alpha_mem_fc_func( func )),\ + *((__alpha_int_32*)(ins))++ #define alpha_encode_mem_br( ins, op, func, Rdest, Rsrc, hint ) \ - *((__alpha_int_32*)(ins))++ = ( 0 |\ + *((__alpha_int_32*)(ins)) = ( 0 |\ alpha_opcode( op ) | alpha_reg_a( Rdest ) | \ - alpha_reg_b( Rsrc ) | alpha_mem_br_func( func, hint ) ) + alpha_reg_b( Rsrc ) | alpha_mem_br_func( func, hint ) ),\ + ((__alpha_int_32*)(ins))++ #define alpha_encode_branch( ins, op, Reg, offset ) \ - *((__alpha_int_32*)(ins))++ = ( 0 |\ + *((__alpha_int_32*)(ins)) = ( 0 |\ alpha_opcode( op ) | alpha_reg_a( Reg ) | \ - (offset AXP_OFF21_MASK )) + (offset AXP_OFF21_MASK )),\ + ((__alpha_int_32*)(ins))++ #define alpha_encode_op( ins, op, func, Rsrc1, Rsrc2, Rdest ) \ - *((__alpha_int_32*)(ins))++ = ( 0 |\ + *((__alpha_int_32*)(ins)) = ( 0 |\ alpha_opcode( op ) | alpha_reg_a( Rsrc1 ) | \ alpha_reg_b( Rsrc2 ) | alpha_op_func( func ) | \ - alpha_reg_c( Rdest )) + alpha_reg_c( Rdest )),\ + ((__alpha_int_32*)(ins))++ #define alpha_encode_opl( ins, op, func, Rsrc, lit, Rdest ) \ - *((__alpha_int_32*)(ins))++ = ( 0 |\ - alpha_opcode( op ) | alpha_reg_a( Rsrc1 ) | \ + *((__alpha_int_32*)(ins)) = ( 0 |\ + alpha_opcode( op ) | alpha_reg_a( Rsrc ) | \ alpha_op_literal(lit) | ( 1 12 ) | \ - alpha_op_func( func ) | alpha_reg_c( Rdest ) ) + alpha_op_func( func ) | alpha_reg_c( Rdest ) ),\ + ((__alpha_int_32*)(ins))++ #define alpha_encode_fpop( ins, op, func, Rsrc1, Rsrc2, Rdest ) \ - *((__alpha_int_32*)(ins))++ = ( 0 |\ + *((__alpha_int_32*)(ins)) = ( 0 |\ alpha_opcode( op ) | alpha_reg_a( Rsrc1 ) | \ alpha_reg_b( Rsrc2 ) | alpha_fp_func( func ) | \ - alpha_reg_c( Rdest )) + alpha_reg_c( Rdest )),\ + ((__alpha_int_32*)(ins))++ /***/ @@ -504,13 +511,48 @@ #define alpha_extqh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x7a, Rsrc1, Rsrc2, Rdest ) #define alpha_extqh_( ins, Rsrc1, lit, Rdest )alpha_encode_opl( ins, 0x12, 0x7a, Rsrc1, lit, Rdest ) +#define alpha_mull(ins, Rsrc1,
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, Exception support requires implementing: - the opcodes like throw, start_handler, endfinally - the functions in exceptions-ARCH.c - mono_arch_emit_exceptions (). As usual, the best documentation is the code of the other backends, but there is some documentation in mono/docs/exception-handling.txt. I suggest going throu the tests in exceptions.cs in the order they are in the file, and trying to implement the support needed by them. LMF handling can be done at a later stage since it is only needed by some later tests. Hello Zoltan, I did some progress on exception implemetation. Now it can throw and catch them. I got stuck with finding of correct exception handler if an exception is thrown in unmanaged code. In my case the exception is thrown by mono_fconv_ovf_u8 and my current implementation of mono_arch_find_jit_info can't find ji info for it (mono_jit_info_table_find return NULL for it). AMD64 version of mono_arch_find_jit_info expects LMF info for such methods. Do I have to implement LMF support or have to try to find previous frame by analizing stack? Finding of exception handlers for managed code seems to be working. Thank you, PS. At what point I should ask to apply my changes to the main repository? Of cause it is not complete, but there is possibility that someone else would be interested to help and there is a base to start with. -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello Zoltan, Either you should emit code to move from R0 to ins-dreg, or (better), modify your cpu-alpha.md file and the register allocator macros in mini-alpha.h to force the local register allocator to allways allocate the dreg of the call instruction to R0. This way the reg allocator will emit the move instruction if it is neccesary. Here is what a call instruction looks like in cpu-pentium.md: call: dest:a clob:c len:17 And the corresponding macro (only an example): #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'a') ? X86_EAX : -1) Using different options triggered some interesting code I had to implement. My question is what is the difference between local and global registers? As I undertood the local registers could be used temporary in basic blocks, the global registers are used during optimizations. Can I define all my local registers as global ones? It seems that they couldn't mixed. Global registers are used during global register allocation. They should be distinct from the set of local registers. mono_arch_get_global_int_regs () returns the list of registers that should be used for global allocation. These registers are usually the 'callee-saved' registers defined by the platform ABI. The global register allocator will set cfg-used_int_regs if needed. I suggest returning an empty list from get_global_int_regs () until all tests are running, so you have a large set of regression tests which you can use to debug the inevitable problems which will arose when some variables are allocated to global registers. After some hacking I was able to run Hello world program. :) It still crashes somewhere at final stage of program rundown, but surely it did a lot before that. :) Now I have to implement hardest part - handling of exceptions. I need some hints here. :) - Of couse I am getting segfaults. For now I return -1 in mono_arch_find_jit_info. It seems to work in most cases - I am getting stack trace. But I guess there is not enough information to do correct unwinding and the VM segfaults again and goes to the loop of segfaults. If you could shed light here - it would be great. - Do I have to implement LMF handling to do correct unwinding? I don't have any LMF frames right now (it seems that I would have to save a lot of information in stack). - I don't have implemented any of throw, finally, call_handler - program exceptions. What are the requirements to implement it in general? Thank you, -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
: alpha_r14 [1 - 9] liveness: R31 [5 - 7] liveness: R32 [6 - 7] liveness: R33 [7 - 8] liveness: R34 [9 - 10] processing: 10 move alpha_r0 - R34 assigned sreg1 alpha_r0 to R34 10 move alpha_r0 - alpha_r0 processing: 9 move R34 - alpha_r14 assigned dreg alpha_r0 to dest R34 freeable alpha_r0 (R34) (born in 9) 9 move alpha_r0 - alpha_r14 processing: 8 move alpha_r14 - R33 assigned sreg1 alpha_r14 to R33 8 move alpha_r14 - alpha_r14 processing: 7 call R33 - clobbers: c assigned dreg alpha_r14 to dest R33 freeable alpha_r14 (R33) (born in 7) assigned arg reg alpha_r17 to R31 assigned arg reg alpha_r16 to R32 7 call alpha_r14 - clobbers: c processing: 6 move R32 - alpha_r14 assigned dreg alpha_r16 to dest R32 freeable alpha_r16 (R32) (born in 6) 6 move alpha_r16 - alpha_r14 processing: 5 move R31 - alpha_r13 assigned dreg alpha_r17 to dest R31 freeable alpha_r17 (R31) (born in 5) 5 move alpha_r17 - alpha_r13 processing: 4 iconst alpha_r13 - 4 iconst alpha_r13 - processing: 3 iconst alpha_r14 - 3 iconst alpha_r14 - processing: 2 iconst alpha_r13 - 2 iconst alpha_r13 - processing: 1 iconst alpha_r14 - 1 iconst alpha_r14 - ** (process:23165): DEBUG: ALPHA_DEBUG: mono_arch_local_regalloc is called. ** (process:23165): DEBUG: ALPHA_DEBUG: mono_arch_emit_prolog is called. ** (process:23165): DEBUG: ALPHA_DEBUG: mono_arch_output_basic_block is called. Basic block 0(0x12042a8f8) starting at offset 0x18 ** (process:23165): DEBUG: ALPHA_DEBUG: mono_arch_output_basic_block is called. Basic block 3(0x12042abf8) starting at offset 0x18 ALPHA: Emiting [iconst] opcode ALPHA_CHECK: [iconst] dreg=14, const=0 ALPHA: Emiting [iconst] opcode ALPHA_CHECK: [iconst] dreg=13, const=0 ALPHA: Emiting [iconst] opcode ALPHA_CHECK: [iconst] dreg=14, const=6 ALPHA: Emiting [iconst] opcode ALPHA_CHECK: [iconst] dreg=13, const=3 ALPHA: Emiting [move] opcode ALPHA_CHECK: [move] sreg=13, dreg=17 ALPHA: Emiting [move] opcode ALPHA_CHECK: [move] sreg=14, dreg=16 ALPHA: Emiting [call] opcode ALPHA_CHECK: [fcall/lcall/vcall/voidcall/call] Target: [MONO_PATCH_INFO_ABS] 0x120152068 ALPHA: Emiting [move] opcode ** (process:23165): DEBUG: ALPHA_DEBUG: mono_arch_output_basic_block is called. ALPHA_CHECK: [move] sreg=14, dreg=0 Basic block 1(0x12042a9f8) starting at offset 0x50 ** (process:23165): DEBUG: ALPHA_DEBUG: mono_arch_emit_epilog is called. ** (process:23165): DEBUG: ALPHA_DEBUG: mono_arch_emit_exceptions is called. Method Tests:test_2_div () emitted at 0x2000411d2f8 to 0x2000411d35c [basic.exe] ** (process:23165): DEBUG: ALPHA_DEBUG: mono_arch_patch_code is called. /tmp/test.o: file format elf64-alpha Disassembly of section .text: Tests_test_2_div: 0: 00 00 bb 27 ldah gp,0(t12) 4: 00 00 bd 23 lda gp,0(gp) 8: f0 ff de 23 lda sp,-16(sp) c: 00 00 5e b7 stq ra,0(sp) 10: 08 00 fe b5 stq fp,8(sp) 14: 0f 04 fe 47 mov sp,fp 18: 0e 04 ff 47 clr s5 1c: 0d 04 ff 47 clr s4 20: 06 00 df 21 lda s5,6 24: 03 00 bf 21 lda s4,3 28: 11 04 ed 47 mov s4,a1 2c: 10 04 ee 47 mov s5,a0 30: 38 00 7d a7 ldq t12,56(gp) 34: 02 00 e0 c3 br40 Tests_test_2_div+0x40 38: 68 20 15 20 lda v0,8296(a5) 3c: 01 00 00 00 call_pal0x1 40: 00 40 5b 6b jsr ra,(t12),44 Tests_test_2_div+0x44 44: 00 00 ba 27 ldah gp,0(ra) 48: bc ff bd 23 lda gp,-68(gp) 4c: 00 04 ee 47 mov s5,v0 50: 1e 04 ef 47 mov fp,sp 54: 00 00 5e a7 ldq ra,0(sp) 58: 08 00 fe a5 ldq fp,8(sp) 5c: 10 00 de 23 lda sp,16(sp) 60: 01 80 fa 6b ret Running 'test_2_div' ... Test 'test_2_div' failed result (got 6, expected 2). Using different options triggered some interesting code I had to implement. My question is what is the difference between local and global registers? As I undertood the local registers could be used temporary in basic blocks, the global registers are used during optimizations. Can I define all my local registers as global ones? It seems that they couldn't mixed. Another thing that I haven't looked yet is - then global register was used shouldn't register allocation logic mark it as used in cfg-used_int_regs? I have a code in my emit_prolog function that should save used int regs on stack, but it saves none (it might be problem in my code, but I hope my assumption is correct). So far about 99% of basic tests are successful with different optimisation options. :) Regards, PS. Is my assumption is correct that by default all OP_I.. and CEE_... opcodes that work with intergers are 32 bit long? -- Sergey Tikhonov Solvo Ltd. Saint-Petersburg, Russia [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, You can put it into mono_arch_emit_exceptions (). Zoltan Thanks you. I hit another blocking issue - inplementation of OP_OUTARG_VT. Different arches do it differently. Is my understanding is correct - that I could pass it on stack for simplicity (like ia64 does), but the called method should expect it on stack too. This kind of parameter is not expected to be passed to any natively compiled methods (by gcc) (because by Alpha ABI upto 6 parameters are expected to be passed in registers). So if the called method is compiled by jit I guess I have control over where to look for method parameters. I got to the point of calling System.Runtime.CompilerServices.RuntimeHelpers:InitializeArray(System.Array, intptr) and crashing inside. Is there simpler way to check JIT? :) I am using compiled basic.cs as start point, but it tries to initialize part of runtime (I guess) and it is not the simple one. Thank you, -- Sergey Tikhonov Solvo Ltd. [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Hello, I made some progress, but still need help. :) Working with ICONSTs on Alpha is real pain. I would like to do the following: - allocate some memory at the end of method and store ICONSTs there - use some of the registers to hold base address of that memory - load ICONSTs from that memory using offsets from the base Kind of local GOT section for a method. I can put addresses for CALLs there too (doing patching of these addresses is not big issue - I won't need to know structure of instructions). I need some clues how to do it, because the size of that GOT section is not know in advance and allocation of GOT entries is done in mono_arch_output_basic_block and others. I need some arch callback method that is called at the end of method compilation, so I write my collected local GOT section and determine offset to it from the begining of compiled method. Thank you, -- Sergey Tikhonov Solvo Ltd. [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, Defining MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE is the preferred method. Hello, How I have something that produces some code, which of cause doesn't work. :) But I got an idea. I have some problems that someone could help me with. I could not understand what the mono_arch_allocate_vars is supposed to do. I copied it from another arch and it seems to work, but I don't understand it. At what point and for what reason the JIT calls it? Based on the trace the mono_arch_allocate_vars is called when JIT finds calli IL opcode. Another problem is implementing iconst/i8const opcode (it is a simple one but it would help to understand the internals). Alpha doesn't have instructions to load 64bits contstant to a register, but there are other instructions that I could use to emulate this. I need one temporary register, but I could not understand how to reserve it (at what point). Let say I don't want to add new opcode. The definition is iconst opcode in md file uses only one dest register. Thank you, -- Sergey Tikhonov Solvo Ltd. [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Sergey Tikhonov wrote: Jonathan Pryor wrote: On Fri, 2006-01-20 at 20:27 +0300, Sergey Tikhonov wrote: Well, it it really pity since it seem that even this unsupported interpretator does a lot of work and give chance other arches to try Mono. :) Ok, I will see if I could find what the problem is The problem is that it's impossible to have a 100% portable interpreter, because of internal calls and P/Invoke. Both of these invoke native code, either within the runtime itself or within a shared library, and this requires processor-specific code to place parameters in the correct registers, etc. Since processor-specific code is required *anyway*, it was considered reasonable to just require the JIT for most uses, since (afaik) the JIT doesn't require _much_ more custom code than the marshaling code already required... Ok, I just thought that the problem I have is somewhat simple. Anyway, I think I found the way how to track it down (so far it fails in ctor of System.Decimal and based on interpreter trace the ctor is called with some bogus params). Ok, after some debugging - it seems that interpreter works correctly with mscorlib.dll from monolite class/lib directory, but fails with newly built mscorlib.dll. Any way I hit to unsupported feature... Any links/hints what is required to create JIT? I looked through the site and didn't find any usefull info... Only source code is the documentation? Thank you, -- Sergey Tikhonov Solvo Ltd. [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Zoltan Varga wrote: Hi, Mono hasn't been ported to the alpha CPU, only the interpreter is provided which is not really supported. Most likely this causes this problem. As far as I understand - it is only JIT or AOT compilers that are arch dependant. The interpreter seems to be working since the build process got so far. The parser fails to parse Decimal numbers that have letters m or M attached to the end (like 0m). If I delete that m it happily continues. I did some modifications to alpha code in arch directory, so it could be compiler by gcc 4.1 and pass some tests. As far as I understand the mono should work without JIT compiler... The problem is that Fedora project started to integrate the Mono very much and it cause a lot of trouble to AlphaCore project I am working on now. Any hints what it is necessary to do port of Mono to Linux/Alpha are welcome, I will try to help (or find someone whoc could help). Thank you, -- Sergey Tikhonov Solvo Ltd. [EMAIL PROTECTED] ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Building Mono on Linux/Alpha
Jonathan Pryor wrote: On Fri, 2006-01-20 at 20:27 +0300, Sergey Tikhonov wrote: Well, it it really pity since it seem that even this unsupported interpretator does a lot of work and give chance other arches to try Mono. :) Ok, I will see if I could find what the problem is The problem is that it's impossible to have a 100% portable interpreter, because of internal calls and P/Invoke. Both of these invoke native code, either within the runtime itself or within a shared library, and this requires processor-specific code to place parameters in the correct registers, etc. Since processor-specific code is required *anyway*, it was considered reasonable to just require the JIT for most uses, since (afaik) the JIT doesn't require _much_ more custom code than the marshaling code already required... Ok, I just thought that the problem I have is somewhat simple. Anyway, I think I found the way how to track it down (so far it fails in ctor of System.Decimal and based on interpreter trace the ctor is called with some bogus params). The arch code for JIT is more complex that trampline code for interpreter (based on the arch JIT code for other arches). Any links/clues what is required for JIT are welcome. :) Thank you, Sergey. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list