From d6b05a8304feacbb82cb253b8b5b4aa2e0bfb592 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Fri, 1 Mar 2013 20:27:07 +0100 Subject: [PATCH] Remove the unmaintained and incomplete alpha backend. --- configure.in | 16 +- mono/arch/Makefile.am | 2 +- mono/arch/alpha/.gitignore | 4 - mono/arch/alpha/Makefile.am | 8 - mono/arch/alpha/alpha-codegen.h | 576 --- mono/arch/alpha/test.c | 156 - mono/arch/alpha/tramp.c | 380 -- mono/io-layer/atomic.h | 111 - mono/metadata/mono-config.c | 6 - mono/mini/Makefile.am.in | 16 - mono/mini/cpu-alpha.md | 400 --- mono/mini/exceptions-alpha.c | 997 ------ mono/mini/mini-alpha.c | 5887 ------------------------------- mono/mini/mini-alpha.h | 308 -- mono/mini/mini-arch.h | 2 - mono/mini/mini-ops.h | 24 - mono/mini/tramp-alpha.c | 632 ---- mono/utils/mono-membar.h | 15 - 18 files changed, 2 insertions(+), 9538 deletions(-) delete mode 100644 mono/arch/alpha/.gitignore delete mode 100644 mono/arch/alpha/Makefile.am delete mode 100644 mono/arch/alpha/alpha-codegen.h delete mode 100644 mono/arch/alpha/test.c delete mode 100644 mono/arch/alpha/tramp.c delete mode 100644 mono/mini/cpu-alpha.md delete mode 100644 mono/mini/exceptions-alpha.c delete mode 100644 mono/mini/mini-alpha.c delete mode 100644 mono/mini/mini-alpha.h delete mode 100644 mono/mini/tramp-alpha.c diff --git a/configure.in b/configure.in index 002b2f6a433..c4645e85e51 100644 --- a/configure.in +++ b/configure.in @@ -2512,18 +2512,6 @@ case "$host" in fi sgen_supported=true ;; - alpha*-*-linux* | alpha*-*-osf*) - TARGET=ALPHA; - ACCESS_UNALIGNED="no" - JIT_SUPPORTED=yes - arch_target=alpha; - CFLAGS="$CFLAGS -mieee -O0" - case $host_os in - linux*) - LIBC="libc.so.6.1" - INTL="libc.so.6.1" - esac - ;; *-mingw*|*-*-cygwin*) # When this is enabled, it leads to very strange crashes at runtime (gcc-3.4.4) have_visibility_hidden=no @@ -2857,7 +2845,7 @@ fi mono_debugger_supported=no AC_ARG_ENABLE(mono-debugger, [ --disable-mono-debugger disable support for the mdb debugger], try_mono_debugger=$enableval, try_mono_debugger=yes) if test "x$try_mono_debugger" = "xyes"; then - if test "x$TARGET" = "xAMD64" -o "x$TARGET" = "xX86" -o "x$TARGET" = "xALPHA" -o "x$TARGET" = "xS390x"; then + if test "x$TARGET" = "xAMD64" -o "x$TARGET" = "xX86" -o "x$TARGET" = "xS390x"; then if test x$use_included_gc = xyes; then case "$host" in *-*-*linux*) @@ -3133,7 +3121,6 @@ AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(SPARC64, test x$TARGET = xSPARC64) AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(AMD64, test x$TARGET = xAMD64) -AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA) AM_CONDITIONAL(IA64, test x$TARGET = xIA64) AM_CONDITIONAL(M68K, test x$TARGET = xM68K) AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) @@ -3336,7 +3323,6 @@ mono/arch/sparc/Makefile mono/arch/s390/Makefile mono/arch/s390x/Makefile mono/arch/arm/Makefile -mono/arch/alpha/Makefile mono/arch/ia64/Makefile mono/arch/mips/Makefile mono/interpreter/Makefile diff --git a/mono/arch/Makefile.am b/mono/arch/Makefile.am index 2cfec09b416..0bedf771efb 100644 --- a/mono/arch/Makefile.am +++ b/mono/arch/Makefile.am @@ -1,4 +1,4 @@ -DIST_SUBDIRS = x86 ppc sparc arm s390 s390x alpha amd64 ia64 mips +DIST_SUBDIRS = x86 ppc sparc arm s390 s390x amd64 ia64 mips AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) diff --git a/mono/arch/alpha/.gitignore b/mono/arch/alpha/.gitignore deleted file mode 100644 index 6abcd22b3ce..00000000000 --- a/mono/arch/alpha/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/Makefile.in -/Makefile -/.deps -/.cvsignore diff --git a/mono/arch/alpha/Makefile.am b/mono/arch/alpha/Makefile.am deleted file mode 100644 index 86cbcb6bfe1..00000000000 --- a/mono/arch/alpha/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ - -AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) - -noinst_LTLIBRARIES = libmonoarch-alpha.la - -libmonoarch_alpha_la_SOURCES = tramp.c alpha-codegen.h - -noinst_PROGRAMS = test diff --git a/mono/arch/alpha/alpha-codegen.h b/mono/arch/alpha/alpha-codegen.h deleted file mode 100644 index 46f95e199d3..00000000000 --- a/mono/arch/alpha/alpha-codegen.h +++ /dev/null @@ -1,576 +0,0 @@ -#ifndef __ALPHA_CODEGEN_H__ -#define __ALPHA_CODEGEN_H__ - -/* - http://ftp.digital.com/pub/Digital/info/semiconductor/literature/alphaahb.pdf -*/ - -typedef enum { - alpha_r0 = 0, - alpha_r1 = 1, - alpha_r2 = 2, - alpha_r3 = 3, - alpha_r4 = 4, - alpha_r5 = 5, - alpha_r6 = 6, - alpha_r7 = 7, - alpha_r8 = 8, - alpha_r9 = 9, - alpha_r10 = 10, - alpha_r11 = 11, - alpha_r12 = 12, - alpha_r13 = 13, - alpha_r14 = 14, - alpha_r15 = 15, - alpha_r16 = 16, - alpha_r17 = 17, - alpha_r18 = 18, - alpha_r19 = 19, - alpha_r20 = 20, - alpha_r21 = 21, - alpha_r22 = 22, - alpha_r23 = 23, - alpha_r24 = 24, - alpha_r25 = 25, - alpha_r26 = 26, - alpha_r27 = 27, - alpha_r28 = 28, - alpha_r29 = 29, - alpha_r30 = 30, - alpha_r31 = 31, alpha_zero = 31, - /* aliases */ - alpha_v0 = 0, /* return value */ - - alpha_t0 = 1, /* temporaries */ - alpha_t1 = 2, - alpha_t2 = 3, - alpha_t3 = 4, - alpha_t4 = 5, - alpha_t5 = 6, - alpha_t6 = 7, - alpha_t7 = 8, - - alpha_s0 = 9, /* saved registers */ - alpha_s1 = 10, - alpha_s2 = 11, - alpha_s3 = 12, - alpha_s4 = 13, - alpha_s5 = 14, - alpha_s6 = 15, - - alpha_fp = 15, /* frame pointer */ - - alpha_a0 = 16, /* argument registers */ - alpha_a1 = 17, - alpha_a2 = 18, - alpha_a3 = 19, - alpha_a4 = 20, - alpha_a5 = 21, - - alpha_t8 = 22, /* temporaries */ - alpha_t9 = 23, - alpha_t10 = 24, - alpha_t11 = 25, - - alpha_ra = 26, /* Return Address */ - - alpha_pv = 27, /* pv current procedure */ - alpha_t12 = 27, /* temp 12 */ - - alpha_altreg = 28, - alpha_at = 28, - - alpha_gp = 29, /* Global Pointer */ - alpha_sp = 30, /* Stack Pointer */ -} AlphaRegister; - -typedef enum { - /* floating point registers */ - alpha_f0 = 0, - alpha_f1 = 1, - alpha_f2 = 2, - alpha_f3 = 3, - alpha_f4 = 4, - alpha_f5 = 5, - alpha_f6 = 6, - alpha_f7 = 7, - alpha_f8 = 8, - alpha_f9 = 9, - alpha_f10 = 10, - alpha_f11 = 11, - alpha_f12 = 12, - alpha_f13 = 13, - alpha_f14 = 14, - alpha_f15 = 15, - alpha_f16 = 16, - alpha_f17 = 17, - alpha_f18 = 18, - alpha_f19 = 19, - alpha_f20 = 20, - alpha_f21 = 21, - alpha_f22 = 22, - alpha_f23 = 23, - alpha_f24 = 24, - alpha_f25 = 25, - alpha_f26 = 26, - alpha_f27 = 27, - alpha_f28 = 28, - alpha_f29 = 29, - alpha_f30 = 30, - alpha_f31 = 31, alpha_fzero = 31, - /* aliases */ - alpha_fv0 = 0, /* return value */ - alpha_fv1 = 1, - - alpha_fs0 = 2, /* saved registers */ - alpha_fs1 = 3, - alpha_fs2 = 4, - alpha_fs3 = 5, - alpha_fs4 = 6, - alpha_fs5 = 7, - alpha_fs6 = 8, - alpha_fs7 = 9, - - alpha_ft0 = 10, /* temporary */ - alpha_ft1 = 11, - alpha_ft2 = 12, - alpha_ft3 = 13, - alpha_ft4 = 14, - alpha_ft5 = 15, - - alpha_fa0 = 16, /* args */ - alpha_fa1 = 17, - alpha_fa2 = 18, - alpha_fa3 = 19, - alpha_fa4 = 20, - alpha_fa5 = 21, - - alpha_ft6 = 22, - alpha_ft7 = 23, - alpha_ft8 = 24, - alpha_ft9 = 25, - alpha_ft10 = 26, - alpha_ft11 = 27, - alpha_ft12 = 28, - alpha_ft13 = 29, - alpha_ft14 = 30 -} AlphaFPRegister; - -/***************************************/ - -#define __alpha_int_32 unsigned int - -/***************************************/ -#define AXP_OFF26_MASK 0x03ffffff -#define AXP_OFF21_MASK 0x01fffff -#define AXP_OFF16_MASK 0x0ffff -#define AXP_OFF14_MASK 0x03fff -#define AXP_OFF13_MASK 0x01fff -#define AXP_OFF11_MASK 0x07ff -#define AXP_OFF8_MASK 0x0ff -#define AXP_OFF7_MASK 0x07f -#define AXP_OFF6_MASK 0x03f -#define AXP_OFF5_MASK 0x01f -#define AXP_OFF4_MASK 0x0f -#define AXP_OFF2_MASK 0x03 -#define AXP_OFF1_MASK 0x01 - - -#define AXP_REG_MASK AXP_OFF5_MASK -#define AXP_REGSIZE 5 - -#define AXP_OP_SHIFT 26 -#define AXP_REG1_SHIFT 21 -#define AXP_REG2_SHIFT 16 -#define AXP_MEM_BR_SHIFT 14 -#define AXP_LIT_SHIFT 13 - -/* encode registers */ -#define alpha_opcode( op ) \ - ((op&AXP_OFF6_MASK) << AXP_OP_SHIFT) - -/* encode registers */ -#define alpha_reg_a( reg ) \ - ((reg & AXP_REG_MASK) << AXP_REG1_SHIFT) - -#define alpha_reg_b( reg ) \ - ((reg & AXP_REG_MASK) << AXP_REG2_SHIFT) - -#define alpha_reg_c( reg ) \ - (reg & AXP_REG_MASK) - - - -/* encode function codes */ -#define alpha_fp_func( func ) \ - ((func & AXP_OFF11_MASK) << AXP_REGSIZE) - -#define alpha_op_func( func ) \ - ((func & AXP_OFF7_MASK) << AXP_REGSIZE) - -#define alpha_op_literal( lit ) \ - ((lit & AXP_OFF8_MASK) << AXP_LIT_SHIFT) - -#define alpha_mem_br_func( func, hint ) \ - (((func & AXP_OFF2_MASK ) << AXP_MEM_BR_SHIFT ) | (hint&AXP_OFF14_MASK)) - -#define alpha_mem_fc_func( func ) \ - (func && AXP_OFF16_MASK) - - -#define alpha_encode_hw4_mem( op, func ) \ - (alpha_opcode( op ) | (( func & 0x0f ) << 12)) - -#define alpha_encode_hw5_mem( op, func ) \ - (alpha_opcode( op ) | (( func & 0x3f ) << 10)) - -#define alpha_encode_hw6mem( op, func ) \ - (alpha_opcode( op ) | (( func & 0x0f ) << 12)) - -#define alpha_encode_hw6mem_br( op, func ) \ - (alpha_opcode( op ) | (( func & 0x07 ) << 13)) - - -/*****************************************/ - - -#define alpha_encode_palcall( ins, op, func ) \ - *((__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_opcode( op ) | alpha_reg_a( Rdest ) | \ - 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_opcode( op ) | alpha_reg_a( Rdest ) | \ - 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_opcode( op ) | alpha_reg_a( Rdest ) | \ - 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_opcode( op ) | alpha_reg_a( Reg ) | \ - (offset & AXP_OFF21_MASK )),\ - ((__alpha_int_32*)(ins))++ - -#define alpha_encode_op( ins, op, func, Rsrc1, Rsrc2, Rdest ) \ - *((__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_int_32*)(ins))++ - - -#define alpha_encode_opl( ins, op, func, Rsrc, lit, Rdest ) \ - *((__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_int_32*)(ins))++ - - -#define alpha_encode_fpop( ins, op, func, Rsrc1, Rsrc2, Rdest ) \ - *((__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_int_32*)(ins))++ - - -/***************************************/ - -/* pal calls */ -/* #define alpha_halt( ins ) alpha_encode_palcall( ins, 0, 0 ) */ - -#define alpha_call_pal( ins, func ) alpha_encode_palcall( ins, 0, func ) - -/*memory*/ -#define alpha_lda( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x08, Rdest, Rsrc, offset ) -#define alpha_ldah( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x09, Rdest, Rsrc, offset ) -#define alpha_ldbu( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x0a, Rdest, Rsrc, offset ) -#define alpha_ldq_u( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x0b, Rdest, Rsrc, offset ) -#define alpha_ldwu( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x0c, Rdest, Rsrc, offset ) -#define alpha_stw( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x0d, Rdest, Rsrc, offset ) -#define alpha_stb( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x0e, Rdest, Rsrc, offset ) -#define alpha_stq_u( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x0f, Rdest, Rsrc, offset ) - -#ifdef __VAX__ -#define alpha_ldf( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x20, Rdest, Rsrc, offset ) -#define alpha_ldg( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x21, Rdest, Rsrc, offset ) -#define alpha_stf( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x24, Rdest, Rsrc, offset ) -#define alpha_stg( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x25, Rdest, Rsrc, offset ) -#endif - -#define alpha_lds( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x22, Rdest, Rsrc, offset ) -#define alpha_ldt( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x23, Rdest, Rsrc, offset ) -#define alpha_ldqf( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x23, Rdest, Rsrc, offset ) - -#define alpha_sts( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x26, Rdest, Rsrc, offset ) -#define alpha_stt( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x27, Rdest, Rsrc, offset ) -#define alpha_stqf( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x27, Rdest, Rsrc, offset ) - - -#define alpha_ldl( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x28, Rdest, Rsrc, offset ) -#define alpha_ldq( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x29, Rdest, Rsrc, offset ) -#define alpha_ldl_l( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x2A, Rdest, Rsrc, offset ) -#define alpha_ldq_l( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x2B, Rdest, Rsrc, offset ) -#define alpha_stl( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x2C, Rdest, Rsrc, offset ) -#define alpha_stq( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x2D, Rdest, Rsrc, offset ) -#define alpha_stl_c( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x2E, Rdest, Rsrc, offset ) -#define alpha_stq_c( ins, Rdest, Rsrc, offset ) alpha_encode_mem( ins, 0x2F, Rdest, Rsrc, offset ) - - -/* branch*/ -#define alpha_jmp( ins, Rdest, Rsrc, hint ) alpha_encode_mem_br( ins, 0x1A, 0x0, Rdest, Rsrc, hint ) -#define alpha_jsr( ins, Rdest, Rsrc, hint ) alpha_encode_mem_br( ins, 0x1A, 0x1, Rdest, Rsrc, hint ) -#define alpha_ret( ins, Rsrc, hint ) alpha_encode_mem_br( ins, 0x1A, 0x2, alpha_zero, Rsrc, hint ) -#define alpha_jsrco( ins, Rdest, Rsrc, hint ) alpha_encode_mem_br( ins, 0x1A, 0x3, Rdest, Rsrc, hint ) - -#define alpha_br( ins, Reg, offset ) alpha_encode_branch( ins, 0x30, Reg, offset ) -#define alpha_fbeq( ins, Reg, offset ) alpha_encode_branch( ins, 0x31, Reg, offset ) -#define alpha_fblt( ins, Reg, offset ) alpha_encode_branch( ins, 0x32, Reg, offset ) -#define alpha_fble( ins, Reg, offset ) alpha_encode_branch( ins, 0x33, Reg, offset ) -#define alpha_bsr( ins, Reg, offset ) alpha_encode_branch( ins, 0x34, Reg, offset ) -#define alpha_fbne( ins, Reg, offset ) alpha_encode_branch( ins, 0x35, Reg, offset ) -#define alpha_fbge( ins, Reg, offset ) alpha_encode_branch( ins, 0x36, Reg, offset ) -#define alpha_fbgt( ins, Reg, offset ) alpha_encode_branch( ins, 0x37, Reg, offset ) -#define alpha_blbc( ins, Reg, offset ) alpha_encode_branch( ins, 0x38, Reg, offset ) -#define alpha_beq( ins, Reg, offset ) alpha_encode_branch( ins, 0x39, Reg, offset ) -#define alpha_blt( ins, Reg, offset ) alpha_encode_branch( ins, 0x3A, Reg, offset ) -#define alpha_ble( ins, Reg, offset ) alpha_encode_branch( ins, 0x3B, Reg, offset ) -#define alpha_blbs( ins, Reg, offset ) alpha_encode_branch( ins, 0x3C, Reg, offset ) -#define alpha_bne( ins, Reg, offset ) alpha_encode_branch( ins, 0x3D, Reg, offset ) -#define alpha_bge( ins, Reg, offset ) alpha_encode_branch( ins, 0x3E, Reg, offset ) -#define alpha_bgt( ins, Reg, offset ) alpha_encode_branch( ins, 0x3F, Reg, offset ) - - -/* integer */ -/*//#define alpha_sextl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x00, Rsrc1, Rsrc2, Rdest ) -//#define alpha_sextl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x00, Rsrc1, lit, Rdest ) -*/ -#define alpha_addl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x00, Rsrc1, Rsrc2, Rdest ) -#define alpha_addl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x00, Rsrc1, lit, Rdest ) -#define alpha_s4addl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x02, Rsrc1, Rsrc2, Rdest ) -#define alpha_s4addl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x02, Rsrc1, lit, Rdest ) -//#define alpha_negl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x09, Rsrc1, Rsrc2, Rdest ) -//#define alpha_negl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x09, Rsrc1, lit, Rdest ) -#define alpha_subl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x09, Rsrc1, Rsrc2, Rdest ) -#define alpha_subl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x09, Rsrc1, lit, Rdest ) -#define alpha_s4subl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x0B, Rsrc1, Rsrc2, Rdest ) -#define alpha_s4subl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x0B, Rsrc1, lit, Rdest ) -#define alpha_cmpbge( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x0F, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmpbge_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x0F, Rsrc1, lit, Rdest ) -#define alpha_s8addl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x12, Rsrc1, Rsrc2, Rdest ) -#define alpha_s8addl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x12, Rsrc1, lit, Rdest ) -#define alpha_s8subl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x1B, Rsrc1, Rsrc2, Rdest ) -#define alpha_s8subl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x1B, Rsrc1, lit, Rdest ) -#define alpha_cmpult( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x1d, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmpult_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x1d, Rsrc1, lit, Rdest ) -#define alpha_addq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x20, Rsrc1, Rsrc2, Rdest ) -#define alpha_addq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x20, Rsrc1, lit, Rdest ) -#define alpha_s4addq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x22, Rsrc1, Rsrc2, Rdest ) -#define alpha_s4addq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x22, Rsrc1, lit, Rdest ) -//#define alpha_negq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x29, Rsrc1, Rsrc2, Rdest ) -//#define alpha_negq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x29, Rsrc1, lit, Rdest ) -#define alpha_subq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x29, Rsrc1, Rsrc2, Rdest ) -#define alpha_subq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x29, Rsrc1, lit, Rdest ) -#define alpha_s4subq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x2B, Rsrc1, Rsrc2, Rdest ) -#define alpha_s4subq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x2B, Rsrc1, lit, Rdest ) -#define alpha_cmpeq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x2D, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmpeq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x2D, Rsrc1, lit, Rdest ) -#define alpha_s8addq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x32, Rsrc1, Rsrc2, Rdest ) -#define alpha_s8addq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x32, Rsrc1, lit, Rdest ) -#define alpha_s8subq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x3B, Rsrc1, Rsrc2, Rdest ) -#define alpha_s8subq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x3B, Rsrc1, lit, Rdest ) -#define alpha_cmpule( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x3D, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmpule_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x3D, Rsrc1, lit, Rdest ) -#define alpha_addlv( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x40, Rsrc1, Rsrc2, Rdest ) -#define alpha_addlv_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x40, Rsrc1, lit, Rdest ) -//#define alpha_neglv( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x49, Rsrc1, Rsrc2, Rdest ) -//#define alpha_neglv_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x49, Rsrc1, lit, Rdest ) -#define alpha_sublv( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x49, Rsrc1, Rsrc2, Rdest ) -#define alpha_sublv_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x49, Rsrc1, lit, Rdest ) -#define alpha_cmplt( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x4D, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmplt_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x4D, Rsrc1, lit, Rdest ) -#define alpha_addqv( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x60, Rsrc1, Rsrc2, Rdest ) -#define alpha_addqv_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x60, Rsrc1, lit, Rdest ) -//#define alpha_negqv( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x69, Rsrc1, Rsrc2, Rdest ) -//#define alpha_negqv_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x69, Rsrc1, lit, Rdest ) -#define alpha_subqv( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x69, Rsrc1, Rsrc2, Rdest ) -#define alpha_subqv_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x69, Rsrc1, lit, Rdest ) -#define alpha_cmple( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x10, 0x6D, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmple_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x10, 0x6D, Rsrc1, lit, Rdest ) - -#define alpha_and( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x00, Rsrc1, Rsrc2, Rdest ) -#define alpha_and_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x00, Rsrc1, lit, Rdest ) -//#define alpha_andnot( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x08, Rsrc1, Rsrc2, Rdest ) -//#define alpha_andnot_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x08, Rsrc1, lit, Rdest ) -#define alpha_bic( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x08, Rsrc1, Rsrc2, Rdest ) -#define alpha_bic_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x08, Rsrc1, lit, Rdest ) -#define alpha_cmovlbs( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x14, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmovlbs_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x14, Rsrc1, lit, Rdest ) -#define alpha_cmovlbc( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x16, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmovlbc_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x16, Rsrc1, lit, Rdest ) -#define alpha_nop( ins ) alpha_encode_op( ins, 0x11, 0x20, alpha_zero, alpha_zero, alpha_zero ) -#define alpha_clr( ins, Rdest ) alpha_encode_op( ins, 0x11, 0x20, alpha_zero, alpha_zero, Rdest ) -#define alpha_mov1( ins, Rsrc, Rdest ) alpha_encode_op( ins, 0x11, 0x20, alpha_zero, Rsrc, Rdest ) -#define alpha_mov2( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x20, Rsrc1, Rsrc2, Rdest ) -#define alpha_mov_( ins, lit, Rdest ) alpha_encode_op( ins, 0x11, 0x20, alpha_zero, lit, Rdest ) -//#define alpha_or( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x20, Rsrc1, Rsrc2, Rdest ) -//#define alpha_or_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x20, Rsrc1, lit, Rdest ) -#define alpha_bis( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x20, Rsrc1, Rsrc2, Rdest ) -#define alpha_bis_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x20, Rsrc1, lit, Rdest ) -#define alpha_cmoveq( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x24, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmoveq_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x24, Rsrc1, lit, Rdest ) -#define alpha_cmovne( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x26, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmovne_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x26, Rsrc1, lit, Rdest ) -#define alpha_not( ins, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x28, alpha_zero, Rsrc2, Rdest ) -#define alpha_not_( ins, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x28, alpha_zero, lit, Rdest ) -#define alpha_ornot( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x28, Rsrc1, Rsrc2, Rdest ) -#define alpha_ornot_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x28, Rsrc1, lit, Rdest ) -#define alpha_xor( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x40, Rsrc1, Rsrc2, Rdest ) -#define alpha_xor_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x40, Rsrc1, lit, Rdest ) -#define alpha_cmovlt( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x44, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmovlt_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x44, Rsrc1, lit, Rdest ) -#define alpha_cmovge( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x46, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmovge_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x46, Rsrc1, lit, Rdest ) -#define alpha_eqv( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x48, Rsrc1, Rsrc2, Rdest ) -#define alpha_eqv_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x48, Rsrc1, lit, Rdest ) -//#define alpha_xornot( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x48, Rsrc1, Rsrc2, Rdest ) -//#define alpha_xornot_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x48, Rsrc1, lit, Rdest ) -#define alpha_ev56b_amask( ins, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x61, alpha_zero, Rsrc2, Rdest ) -#define alpha_ev56b_amask_( ins, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x61, alpha_zero, lit, Rdest ) -#define alpha_cmovle( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x64, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmovle_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x64, Rsrc1, lit, Rdest ) -#define alpha_cmovgt( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x66, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmovgt_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x66, Rsrc1, lit, Rdest ) -//#define alpha_implver_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x6C, Rsrc1, lit, Rdest ) -#define alpha_cmovgt( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x11, 0x66, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmovgt_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x11, 0x66, Rsrc1, lit, Rdest ) - -#define alpha_mskbl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x02, Rsrc1, Rsrc2, Rdest ) -#define alpha_mskbl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x02, Rsrc1, lit, Rdest ) -#define alpha_extbl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x06, Rsrc1, Rsrc2, Rdest ) -#define alpha_extbl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x06, Rsrc1, lit, Rdest ) -#define alpha_insbl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x0B, Rsrc1, Rsrc2, Rdest ) -#define alpha_insbl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x0B, Rsrc1, lit, Rdest ) -#define alpha_mskwl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x12, Rsrc1, Rsrc2, Rdest ) -#define alpha_mskwl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x12, Rsrc1, lit, Rdest ) -#define alpha_extwl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x16, Rsrc1, Rsrc2, Rdest ) -#define alpha_extwl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x16, Rsrc1, lit, Rdest ) -#define alpha_inswl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x1b, Rsrc1, Rsrc2, Rdest ) -#define alpha_inswl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x1b, Rsrc1, lit, Rdest ) -#define alpha_mskll( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x22, Rsrc1, Rsrc2, Rdest ) -#define alpha_mskll_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x22, Rsrc1, lit, Rdest ) -#define alpha_extll( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x26, Rsrc1, Rsrc2, Rdest ) -#define alpha_extll_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x26, Rsrc1, lit, Rdest ) -#define alpha_insll( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x2b, Rsrc1, Rsrc2, Rdest ) -#define alpha_insll_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x2b, Rsrc1, lit, Rdest ) -#define alpha_zap( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x30, Rsrc1, Rsrc2, Rdest ) -#define alpha_zap_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x30, Rsrc1, lit, Rdest ) -#define alpha_zapnot( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x31, Rsrc1, Rsrc2, Rdest ) -#define alpha_zapnot_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x31, Rsrc1, lit, Rdest ) -#define alpha_mskql( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x32, Rsrc1, Rsrc2, Rdest ) -#define alpha_mskql_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x32, Rsrc1, lit, Rdest ) -#define alpha_srl( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x34, Rsrc1, Rsrc2, Rdest ) -#define alpha_srl_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x34, Rsrc1, lit, Rdest ) -#define alpha_extql( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x36, Rsrc1, Rsrc2, Rdest ) -#define alpha_extql_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x36, Rsrc1, lit, Rdest ) -#define alpha_sll( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x39, Rsrc1, Rsrc2, Rdest ) -#define alpha_sll_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x39, Rsrc1, lit, Rdest ) -#define alpha_insql( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x3b, Rsrc1, Rsrc2, Rdest ) -#define alpha_insql_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x3b, Rsrc1, lit, Rdest ) -#define alpha_sra( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x3c, Rsrc1, Rsrc2, Rdest ) -#define alpha_sra_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x3c, Rsrc1, lit, Rdest ) -#define alpha_mskwh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x52, Rsrc1, Rsrc2, Rdest ) -#define alpha_mskwh_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x52, Rsrc1, lit, Rdest ) -#define alpha_inswh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x57, Rsrc1, Rsrc2, Rdest ) -#define alpha_inswh_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x57, Rsrc1, lit, Rdest ) -#define alpha_extwh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x5a, Rsrc1, Rsrc2, Rdest ) -#define alpha_extwh_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x5a, Rsrc1, lit, Rdest ) -#define alpha_msklh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x62, Rsrc1, Rsrc2, Rdest ) -#define alpha_msklh_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x62, Rsrc1, lit, Rdest ) -#define alpha_inslh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x67, Rsrc1, Rsrc2, Rdest ) -#define alpha_inslh_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x67, Rsrc1, lit, Rdest ) -#define alpha_extlh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x6a, Rsrc1, Rsrc2, Rdest ) -#define alpha_extlh_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x6a, Rsrc1, lit, Rdest ) -#define alpha_mskqh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x72, Rsrc1, Rsrc2, Rdest ) -#define alpha_mskqh_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x72, Rsrc1, lit, Rdest ) -#define alpha_insqh( ins, Rsrc1, Rsrc2, Rdest ) alpha_encode_op( ins, 0x12, 0x77, Rsrc1, Rsrc2, Rdest ) -#define alpha_insqh_( ins, Rsrc1, lit, Rdest ) alpha_encode_opl( ins, 0x12, 0x77, Rsrc1, lit, Rdest ) -#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, Rsrc2, Rdest) alpha_encode_op( ins, 0x13, 0x00, Rsrc1, Rsrc2, Rdest ) -#define alpha_mull_(ins, Rsrc1, lit, Rdest) alpha_encode_op( ins, 0x13, 0x00, Rsrc1, lit, Rdest ) -#define alpha_mulq(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_op( ins, 0x13, 0x20, Rsrc1, Rsrc2, Rdest ) -#define alpha_mulq_(ins, Rsrc1, lit, Rdest) alpha_encode_op( ins, 0x13, 0x20, Rsrc1, lit, Rdest ) - -#define alpha_sextb(ins, Rsrc2, Rdest) alpha_encode_op( ins, 0x1c, 0x00, alpha_zero, Rsrc2, Rdest ) -#define alpha_sextw(ins, Rsrc2, Rdest) alpha_encode_op( ins, 0x1c, 0x01, alpha_zero, Rsrc2, Rdest ) - -// For 264 -#define alpha_ftois( ins, RFsrc, Rdest ) alpha_encode_fpop( ins, 0x1c, 0x078, RFsrc, alpha_zero, Rdest ) -#define alpha_ftoit( ins, RFsrc, Rdest ) alpha_encode_fpop( ins, 0x1c, 0x070, RFsrc, alpha_zero, Rdest ) -#define alpha_ftoi_qf( ins, RFsrc, Rdest ) alpha_encode_fpop( ins, 0x1c, 0x070, RFsrc, alpha_zero, Rdest ) -// For 264 -#define alpha_itofs( ins, Rsrc, RFdest ) alpha_encode_fpop( ins, 0x14, 0x004, Rsrc, alpha_zero, RFdest ) -#define alpha_itoff( ins, Rsrc, RFdest ) alpha_encode_fpop( ins, 0x14, 0x014, Rsrc, alpha_zero, RFdest ) -#define alpha_itoft( ins, Rsrc, RFdest ) alpha_encode_fpop( ins, 0x14, 0x024, Rsrc, alpha_zero, RFdest ) -#define alpha_itof_qf( ins, Rsrc, RFdest ) alpha_encode_fpop( ins, 0x14, 0x024, Rsrc, alpha_zero, RFdest ) - -#define alpha_cvtts_c(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x2C, alpha_fzero, Rsrc2, Rdest ) -#define alpha_cvttq_c(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x2F, alpha_fzero, Rsrc2, Rdest ) -#define alpha_cvtqs_c(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x3C, alpha_fzero, Rsrc2, Rdest ) -#define alpha_cvtqt_c(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x3E, alpha_fzero, Rsrc2, Rdest ) - - -#define alpha_adds(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x080, Rsrc1, Rsrc2, Rdest ) -#define alpha_subs(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x081, Rsrc1, Rsrc2, Rdest ) -#define alpha_addt(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0A0, Rsrc1, Rsrc2, Rdest ) -#define alpha_subt(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0A1, Rsrc1, Rsrc2, Rdest ) -#define alpha_mult(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0A2, Rsrc1, Rsrc2, Rdest ) -#define alpha_divt(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0A3, Rsrc1, Rsrc2, Rdest ) - -#define alpha_cmptun(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0A4, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmpteq(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0A5, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmptlt(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0A6, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmptle(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0A7, Rsrc1, Rsrc2, Rdest ) - -#define alpha_addt_su(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x5A0, Rsrc1, Rsrc2, Rdest ) -#define alpha_subt_su(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x5A1, Rsrc1, Rsrc2, Rdest ) - - -#define alpha_cmptun_su(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x5A4, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmpteq_su(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x5A5, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmptlt_su(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x5A6, Rsrc1, Rsrc2, Rdest ) -#define alpha_cmptle_su(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x5A7, Rsrc1, Rsrc2, Rdest ) - -#define alpha_cvtts(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0AC, alpha_fzero, Rsrc2, Rdest ) -#define alpha_cvttq(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0AF, alpha_fzero, Rsrc2, Rdest ) -#define alpha_cvtqs(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0BC, alpha_fzero, Rsrc2, Rdest ) -#define alpha_cvtqt(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x0BE, alpha_fzero, Rsrc2, Rdest ) - -#define alpha_divt_su(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x5A3, Rsrc1, Rsrc2, Rdest ) - -#define alpha_cvtts_su(ins, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x16, 0x5AC, alpha_fzero, Rsrc2, Rdest ) - -#define alpha_cpys(ins, Rsrc1, Rsrc2, Rdest) alpha_encode_fpop( ins, 0x17, 0x020, Rsrc1, Rsrc2, Rdest ) -#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_mem_fc( ins, 0x18, 0x0000, 0, 0, 0 ) -#define alpha_mb(ins) alpha_encode_mem_fc( ins, 0x18, 0x4000, 0, 0, 0 ) - -#endif - diff --git a/mono/arch/alpha/test.c b/mono/arch/alpha/test.c deleted file mode 100644 index b922750640c..00000000000 --- a/mono/arch/alpha/test.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "alpha-codegen.h" - -#include -#include -#include -#include -#include -#include -#include - -/* A typical Alpha stack frame looks like this */ -/* -fun: // called from outside the module. - ldgp gp,0(pv) // load the global pointer -fun..ng: // called from inside the module. - lda sp, -SIZE( sp ) // grow the stack downwards. - - stq ra, 0(sp) // save the return address. - - stq s0, 8(sp) // callee-saved registers. - stq s1, 16(sp) // ... - - // Move the arguments to the argument registers... - - mov addr, pv // Load the callee address - jsr ra, (pv) // call the method. - ldgp gp, 0(ra) // restore gp - - // return value is in v0 - - ldq ra, 0(sp) // free stack frame - ldq s0, 8(sp) // restore callee-saved registers. - ldq s1, 16(sp) - ldq sp, 32(sp) // restore stack pointer - - ret zero, (ra), 1 // return. -*/ - - - -// -// Simple function which returns 10. -// -static int testfunc(void) -{ - return 10; -} - -// Write it using the known asm bytecodes. -static unsigned int * write_testfunc_1(unsigned int * p ) -{ -// -// ldah gp, 0(pv) -// lda gp, 0(gp) -//00000001200004d0 : -// 1200004d0: f0 ff de 23 lda sp,-16(sp) -// 1200004d4: 00 00 5e b7 stq ra,0(sp) -// 1200004d8: 08 00 fe b5 stq fp,8(sp) -// 1200004dc: 0f 04 fe 47 mov sp,fp -// 1200004e0: 0a 00 3f 20 lda t0,10 -// 1200004e4: 00 04 e1 47 mov t0,v0 -// 1200004e8: 1e 04 ef 47 mov fp,sp -// 1200004ec: 00 00 5e a7 ldq ra,0(sp) -// 1200004f0: 08 00 fe a5 ldq fp,8(sp) -// 1200004f4: 10 00 de 23 lda sp,16(sp) -// 1200004f8: 01 80 fa 6b ret - -int _func_code[] = { - 0x23defff0, - 0xb75e0000, - 0xb5fe0008, - 0x47fe040f, - 0x203f000a, - 0x47e10400, - 0x47ef041e, - 0xa75e0000, - 0xa5fe0008, - 0x23de0010, - 0x6bfa8001 }; - - memcpy( p , _func_code, 4 * 11 ); - return p + ( 4 * 11 ); -} - -// The same function encoded with alpha-codegen.h -unsigned int * write_testfunc_2( unsigned int * p ) -{ - alpha_ldah( p, alpha_gp, alpha_pv, 0 ); // start the gp load - alpha_lda( p, alpha_sp, alpha_sp, -16 ); // allocate the stack - alpha_lda( p, alpha_gp, alpha_gp, 0 ); // finish the gp load - alpha_stq( p, alpha_ra, alpha_sp, 0 ); // start param save. - alpha_stq( p, alpha_fp, alpha_sp, 8 ); - alpha_mov1( p, alpha_sp, alpha_fp ); - alpha_lda( p, alpha_t0, alpha_zero, 10 ); - alpha_mov1( p, alpha_t0, alpha_v0 ); - alpha_mov1( p, alpha_fp, alpha_sp ); - alpha_ldq( p, alpha_ra, alpha_sp, 0 ); - alpha_ldq( p, alpha_fp, alpha_sp, 8 ); - alpha_lda( p, alpha_sp, alpha_sp, 16 ); - - alpha_ret( p, alpha_ra, 1 ); - - return p; -} - - -void output( char * p, int len ) -{ - char * maxp = p + len; - char * cp = p; - - printf (".text\n.align 4\n.globl main\n.type main,@function\nmain:\n"); - for ( ; cp < maxp; cp++ ) - { - printf (".byte 0x%0.2x\n", (*cp&0x00ff) ); - } - - int fd = open( "bad.out", O_CREAT | O_TRUNC ); - write( fd, p, len ); - close( fd ); -} - -unsigned int code [16000/4]; - -int main( int argc, char ** argv ) { -// unsigned int code [16000/4]; - unsigned int *p = code; - unsigned int * cp; - - int (*x)() = 0; - int y = 0; - int z = 10; - - // so, `test blah` gets you the byte-encoded function. - // and `test` gets you the alpha-codegen.h encoded function. - - if( argc > 1 ) - { - p = write_testfunc_1( p ); - } - else - { - p = write_testfunc_2( p ); - } - - // output( code, p-code ); - - // call the procedure. - x = (int(*)())code; - - while( z-- > 0 ) - y = x(); - - return 0; -} - diff --git a/mono/arch/alpha/tramp.c b/mono/arch/alpha/tramp.c deleted file mode 100644 index 23c3846e0a4..00000000000 --- a/mono/arch/alpha/tramp.c +++ /dev/null @@ -1,380 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Create trampolines to invoke arbitrary functions. - * - * Copyright (C) Ximian Inc. - * - * Authors: Laramie Leavitt (lar@leavitt.us) - * - * - */ - -/* A typical Alpha stack frame looks like this */ -/* -fun: // called from outside the module. - ldgp gp,0(pv) // load the global pointer -fun..ng: // called from inside the module. - lda sp, -SIZE( sp ) // grow the stack downwards. - - stq ra, 0(sp) // save the return address. - - stq s0, 8(sp) // callee-saved registers. - stq s1, 16(sp) // ... - - // Move the arguments to the argument registers... - - mov addr, pv // Load the callee address - jsr ra, (pv) // call the method. - ldgp gp, 0(ra) // restore gp - - // return value is in v0 - - ldq ra, 0(sp) // free stack frame - ldq s0, 8(sp) // restore callee-saved registers. - ldq s1, 16(sp) - ldq sp, 32(sp) // restore stack pointer - - ret zero, (ra), 1 // return. - -// min SIZE = 48 -// our call must look like this. - -call_func: - ldgp gp, 0(pv) -call_func..ng: - .prologue - lda sp, -SIZE(sp) // grow stack SIZE bytes. - stq ra, SIZE-48(sp) // store ra - stq fp, SIZE-40(sp) // store fp (frame pointer) - stq a0, SIZE-32(sp) // store args. a0 = func - stq a1, SIZE-24(sp) // a1 = retval - stq a2, SIZE-16(sp) // a2 = this - stq a3, SIZE-8(sp) // a3 = args - mov sp, fp // set frame pointer - mov pv, a0 // func - - .calling_arg_this - mov a1, a2 - - .calling_arg_6plus - ldq t0, POS(a3) - stq t0, 0(sp) - ldq t1, POS(a3) - stq t1, 8(sp) - ... SIZE-56 ... - - mov zero,a1 - mov zero,a2 - mov zero,a3 - mov zero,a4 - mov zero,a5 - - .do_call - jsr ra, (pv) // call func - ldgp gp, 0(ra) // restore gp. - mov v0, t1 // move return value into t1 - - .do_store_retval - ldq t0, SIZE-24(fp) // load retval into t2 - stl t1, 0(t0) // store value. - - .finished - mov fp,sp - ldq ra,SIZE-48(sp) - ldq fp,SIZE-40(sp) - lda sp,SIZE(sp) - ret zero,(ra),1 - - -*/ -/*****************************************************/ - -#include "config.h" -#include -#include - -#include "alpha-codegen.h" - -#include "mono/metadata/class.h" -#include "mono/metadata/tabledefs.h" -#include "mono/interpreter/interp.h" -#include "mono/metadata/appdomain.h" -#include "mono/metadata/debug-helpers.h" - -#define AXP_GENERAL_REGS 6 -#define AXP_MIN_STACK_SIZE 24 -#define ARG_SIZE sizeof(stackval) -#define ARG_LOC(x) (x * sizeof( stackval ) ) - -/*****************************************************/ - -/* */ -/* void func (void (*callme)(), void *retval, */ -/* void *this_obj, stackval *arguments); */ -static inline unsigned int * -emit_prolog (unsigned int *pi, const gint SIZE, int hasthis ) -{ - unsigned int *p = (unsigned int *)pi; - // 9 instructions. - alpha_ldah( p, alpha_gp, alpha_pv, 0 ); - alpha_lda( p, alpha_gp, alpha_gp, 0 ); // ldgp gp, 0(pv) - alpha_lda( p, alpha_sp, alpha_sp, -((SIZE & 8) ? (SIZE+8) : SIZE) ); // grow stack down SIZE (align to 16 bytes like gcc does) - - /* TODO: we really don't need to store everything. - alpha_a1: We have to store this in order to return the retval. - - alpha_a0: func pointer can be moved directly to alpha_pv - alpha_a3: don't need args after we are finished. - alpha_a2: will be moved into alpha_a0... if hasthis is true. - */ - /* store parameters on stack.*/ - alpha_stq( p, alpha_ra, alpha_sp, (SIZE-24) ); // ra - alpha_stq( p, alpha_fp, alpha_sp, (SIZE-16) ); // fp - alpha_stq( p, alpha_a1, alpha_sp, (SIZE-8) ); // retval - - /* set the frame pointer */ - alpha_mov1( p, alpha_sp, alpha_fp ); - - /* move the args into t0, pv */ - alpha_mov1( p, alpha_a0, alpha_pv ); - alpha_mov1( p, alpha_a3, alpha_t0 ); - - // Move the this pointer into a0. - if( hasthis ) - alpha_mov1( p, alpha_a2, alpha_a0 ); - return p; -} - -static inline unsigned int * -emit_call( unsigned int *pi , const gint SIZE ) -{ - unsigned int *p = (unsigned int *)pi; - - // 3 instructions - /* call func */ - alpha_jsr( p, alpha_ra, alpha_pv, 0 ); // jsr ra, 0(pv) - - /* reload the gp */ - alpha_ldah( p, alpha_gp, alpha_ra, 0 ); - alpha_lda( p, alpha_gp, alpha_gp, 0 ); // ldgp gp, 0(ra) - - return p; -} - -static inline unsigned int * -emit_store_return_default(unsigned int *pi, const gint SIZE ) -{ - // 2 instructions. - unsigned int *p = (unsigned int *)pi; - - /* TODO: This probably do different stuff based on the value. - you know, like stq/l/w. and s/f. - */ - alpha_ldq( p, alpha_t0, alpha_fp, (SIZE-8) ); // load void * retval - alpha_stq( p, alpha_v0, alpha_t0, 0 ); // store the result to *retval. - return p; -} - - -static inline unsigned int * -emit_epilog (unsigned int *pi, const gint SIZE ) -{ - unsigned int *p = (unsigned int *)pi; - - // 5 instructions. - alpha_mov1( p, alpha_fp, alpha_sp ); - - /* restore fp, ra, sp */ - alpha_ldq( p, alpha_ra, alpha_sp, (SIZE-24) ); - alpha_ldq( p, alpha_fp, alpha_sp, (SIZE-16) ); - alpha_lda( p, alpha_sp, alpha_sp, ((SIZE & 8) ? (SIZE+8) : SIZE) ); - - /* return */ - alpha_ret( p, alpha_ra, 1 ); - return p; -} - -static void calculate_size(MonoMethodSignature *sig, int * INSTRUCTIONS, int * STACK ) -{ - int alpharegs; - - alpharegs = AXP_GENERAL_REGS - (sig->hasthis?1:0); - - *STACK = AXP_MIN_STACK_SIZE; - *INSTRUCTIONS = 20; // Base: 20 instructions. - - if( sig->param_count - alpharegs > 0 ) - { - *STACK += ARG_SIZE * (sig->param_count - alpharegs ); - // plus 3 (potential) for each stack parameter. - *INSTRUCTIONS += ( sig->param_count - alpharegs ) * 3; - // plus 2 (potential) for each register parameter. - *INSTRUCTIONS += ( alpharegs * 2 ); - } - else - { - // plus 2 (potential) for each register parameter. - *INSTRUCTIONS += ( sig->param_count * 2 ); - } -} - -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor) -{ - unsigned int *p; - unsigned int *buffer; - MonoType* param; - - int i, pos; - int alpharegs; - int hasthis; - int STACK_SIZE; - int BUFFER_SIZE; - int simple_type; - int regbase; - - // Set up basic stuff. like has this. - hasthis = !!sig->hasthis; - alpharegs = AXP_GENERAL_REGS - hasthis; - regbase = hasthis?alpha_a1:alpha_a0 ; - - // Make a ballpark estimate for now. - calculate_size( sig, &BUFFER_SIZE, &STACK_SIZE ); - - // convert to the correct number of bytes. - BUFFER_SIZE = BUFFER_SIZE * 4; - - - // allocate. - buffer = p = (unsigned int *)malloc(BUFFER_SIZE); - memset( buffer, 0, BUFFER_SIZE ); - pos = 8 * (sig->param_count - alpharegs - 1); - - // Ok, start creating this thing. - p = emit_prolog( p, STACK_SIZE, hasthis ); - - // copy everything into the correct register/stack space - for (i = sig->param_count; --i >= 0; ) - { - param = sig->params [i]; - - if( param->byref ) - { - if( i >= alpharegs ) - { - // load into temp register, then store on the stack - alpha_ldq( p, alpha_t1, alpha_t0, ARG_LOC( i )); - alpha_stq( p, alpha_t1, alpha_sp, pos ); - pos -= 8; - } - else - { - // load into register - alpha_ldq( p, (regbase + i), alpha_t0, ARG_LOC( i ) ); - } - } - else - { - simple_type = param->type; - if( simple_type == MONO_TYPE_VALUETYPE ) - { - if (param->data.klass->enumtype) - simple_type = param->data.klass->enum_basetype->type; - } - - switch (simple_type) - { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - // 4 bytes - need to sign-extend (stackvals are not extended) - if( i >= alpharegs ) - { - // load into temp register, then store on the stack - alpha_ldl( p, alpha_t1, alpha_t0, ARG_LOC( i ) ); - alpha_stq( p, alpha_t1, alpha_sp, pos ); - pos -= 8; - } - else - { - // load into register - alpha_ldl( p, (regbase + i), alpha_t0, (ARG_LOC(i)) ); - } - break; - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_STRING: - case MONO_TYPE_I8: - // 8 bytes - if( i >= alpharegs ) - { - // load into temp register, then store on the stack - alpha_ldq( p, alpha_t1, alpha_t0, ARG_LOC( i ) ); - alpha_stq( p, alpha_t1, alpha_sp, pos ); - pos -= 8; - } - else - { - // load into register - alpha_ldq( p, (regbase + i), alpha_t0, ARG_LOC(i) ); - } - break; - case MONO_TYPE_R4: - case MONO_TYPE_R8: - /* - // floating point... Maybe this does the correct thing. - if( i > alpharegs ) - { - alpha_ldq( p, alpha_t1, alpha_t0, ARG_LOC( i ) ); - alpha_cpys( p, alpha_ft1, alpha_ft1, alpha_ft2 ); - alpha_stt( p, alpha_ft2, alpha_sp, pos ); - pos -= 8; - } - else - { - alpha_ldq( p, alpha_t1, alpha_t0, ARG_LOC(i) ); - alpha_cpys( p, alpha_ft1, alpha_ft1, alpha_fa0 + i + hasthis ); - } - break; - */ - case MONO_TYPE_VALUETYPE: - g_error ("Not implemented: ValueType as parameter to delegate." ); - break; - default: - g_error( "Not implemented: 0x%x.", simple_type ); - break; - } - } - } - - // Now call the function and store the return parameter. - p = emit_call( p, STACK_SIZE ); - p = emit_store_return_default( p, STACK_SIZE ); - p = emit_epilog( p, STACK_SIZE ); - - if( p > buffer + BUFFER_SIZE ) - g_error( "Buffer overflow: got 0x%lx, expected <=0x%x.", (long)(p-buffer), BUFFER_SIZE ); - - /* flush instruction cache to see trampoline code */ - asm volatile("imb":::"memory"); - - return (MonoPIFunc)buffer; -} - -void * -mono_arch_create_method_pointer (MonoMethod *method) -{ - g_error ("Unsupported arch"); - return NULL; -} diff --git a/mono/io-layer/atomic.h b/mono/io-layer/atomic.h index 3172115648e..6d2f767d85b 100644 --- a/mono/io-layer/atomic.h +++ b/mono/io-layer/atomic.h @@ -1110,117 +1110,6 @@ static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add) #endif } -#elif defined(__alpha__) -#define WAPI_ATOMIC_ASM - -static inline gint32 InterlockedCompareExchange(volatile gint32 *dest, - gint32 exch, gint32 comp) -{ - gint32 old, temp, temp2; - long compq = comp, exchq = exch; - - __asm__ __volatile__ ( - "1: ldl_l %2, %0\n" - " mov %2, %1\n" - " cmpeq %2, %5, %3\n" - " cmovne %3, %4, %2\n" - " stl_c %2, %0\n" - " beq %2, 1b\n" - : "=m" (*dest), "=&r" (old), "=&r" (temp), "=&r" (temp2) - : "r" (exchq), "r" (compq), "m" (*dest)); - return(old); -} - -static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp) -{ - gpointer old, temp, temp2; - - __asm__ __volatile__ ( - "1: ldq_l %2, %0\n" - " mov %2, %1\n" - " cmpeq %2, %5, %3\n" - " cmovne %3, %4, %2\n" - " stq_c %2, %0\n" - " beq %2, 1b\n" - : "=m" (*dest), "=&r" (old), "=&r" (temp), "=&r" (temp2) - : "r" (exch), "r" (comp), "m" (*dest)); - return(old); -} - -static inline gint32 InterlockedIncrement(volatile gint32 *val) -{ - gint32 temp, cur; - - __asm__ __volatile__ ( - "1: ldl_l %0, %1\n" - " addl %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)); - return(cur); -} - -static inline gint32 InterlockedDecrement(volatile gint32 *val) -{ - gint32 temp, cur; - - __asm__ __volatile__ ( - "1: ldl_l %0, %1\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)); - return(cur); -} - -static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val) -{ - gint32 ret, temp; - - __asm__ __volatile__ ( - "1: ldl_l %1, %0\n" - " mov %3, %2\n" - " stl_c %2, %0\n" - " beq %2, 1b\n" - : "=m" (*val), "=&r" (ret), "=&r" (temp) - : "r" (new_val), "m" (*val)); - return(ret); -} - -static inline gpointer InterlockedExchangePointer(volatile gpointer *val, gpointer new_val) -{ - gpointer ret, temp; - - __asm__ __volatile__ ( - "1: ldq_l %1, %0\n" - " mov %3, %2\n" - " stq_c %2, %0\n" - " beq %2, 1b\n" - : "=m" (*val), "=&r" (ret), "=&r" (temp) - : "r" (new_val), "m" (*val)); - return(ret); -} - -static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add) -{ - gint32 ret, temp; - - __asm__ __volatile__ ( - "1: ldl_l %2, %0\n" - " mov %2, %1\n" - " addl %2, %3, %2\n" - " stl_c %2, %0\n" - " beq %2, 1b\n" - : "=m" (*val), "=&r" (ret), "=&r" (temp) - : "r" (add), "m" (*val)); - - return(ret); -} - #elif defined(__mips__) #define WAPI_ATOMIC_ASM diff --git a/mono/metadata/mono-config.c b/mono/metadata/mono-config.c index 729cec4a821..88991604f85 100644 --- a/mono/metadata/mono-config.c +++ b/mono/metadata/mono-config.c @@ -78,12 +78,6 @@ #elif defined(__ia64__) #define CONFIG_CPU "ia64" #define CONFIG_WORDSIZE "64" -#elif defined(__alpha__) -#define CONFIG_CPU "alpha" -#define CONFIG_WORDSIZE "64" -#elif defined(hppa) || defined(__hppa__) -#define CONFIG_CPU "hppa" -#define CONFIG_WORDSIZE "32" #elif defined(mips) || defined(__mips) || defined(_mips) #define CONFIG_CPU "mips" #define CONFIG_WORDSIZE "32" diff --git a/mono/mini/Makefile.am.in b/mono/mini/Makefile.am.in index 7cb26d65f7d..0e295328c8d 100644 --- a/mono/mini/Makefile.am.in +++ b/mono/mini/Makefile.am.in @@ -311,12 +311,6 @@ ia64_sources = \ exceptions-ia64.c \ tramp-ia64.c -alpha_sources = \ - mini-alpha.c \ - mini-alpha.h \ - exceptions-alpha.c \ - tramp-alpha.c - darwin_sources = \ mini-darwin.c @@ -502,12 +496,6 @@ arch_built = cpu-ia64.h arch_define=__ia64__ endif -if ALPHA -arch_sources = $(alpha_sources) $(mono_debugger_sources) -arch_built = cpu-alpha.h -arch_define=__alpha__ -endif - if HOST_WIN32 os_sources = $(windows_sources) monobin_platform_ldflags= @@ -633,9 +621,6 @@ cpu-s390x.h: cpu-s390x.md genmdesc$(EXEEXT) cpu-ia64.h: cpu-ia64.md genmdesc$(EXEEXT) $(GENMDESC_PRG) cpu-ia64.h ia64_desc $(srcdir)/cpu-ia64.md -cpu-alpha.h: cpu-alpha.md genmdesc$(EXEEXT) - $(GENMDESC_PRG) cpu-alpha.h alpha_desc $(srcdir)/cpu-alpha.md - cpu-mips.h: cpu-mips.md genmdesc$(EXEEXT) $(GENMDESC_PRG) cpu-mips.h mips_desc $(srcdir)/cpu-mips.md @@ -732,7 +717,6 @@ EXTRA_DIST = TestDriver.cs ldscript ldscript.mono \ $(s390_sources) cpu-s390.md \ $(s390x_sources) cpu-s390x.md \ $(ia64_sources) cpu-ia64.md \ - $(alpha_sources) cpu-alpha.md \ $(windows_sources) \ $(darwin_sources) Info.plist \ $(posix_sources) diff --git a/mono/mini/cpu-alpha.md b/mono/mini/cpu-alpha.md deleted file mode 100644 index c296f034be5..00000000000 --- a/mono/mini/cpu-alpha.md +++ /dev/null @@ -1,400 +0,0 @@ -# Alpha-class cpu description file -# this file is read by genmdesc to pruduce a table with all the relevant information -# about the cpu instructions that may be used by the regsiter allocator, the scheduler -# and other parts of the arch-dependent part of mini. -# -# An opcode name is followed by a colon and optional specifiers. -# A specifier has a name, a colon and a value. Specifiers are separated by white space. -# Here is a description of the specifiers valid for this file and their possible values. -# -# dest:register describes the destination register of an instruction -# src1:register describes the first source register of an instruction -# src2:register describes the second source register of an instruction -# -# i integer register -# b base register (used in address references) -# f floating point register -# a alpha_at register -# -# d EDX register -# l long reg (forced eax:edx) -# s ECX register -# c register which can be used as a byte register (RAX..RDX) -# -# len:number describe the maximun length in bytes of the instruction -# number is a positive integer. If the length is not specified -# it defaults to zero. But lengths are only checked if the given opcode -# is encountered during compilation. Some opcodes, like CONV_U4 are -# transformed into other opcodes in the brg files, so they do not show up -# during code generation. -# -# cost:number describe how many cycles are needed to complete the instruction (unused) -# -# clob:spec describe if the instruction clobbers registers or has special needs -# -# c clobbers caller-save registers -# 1 clobbers the first source register -# a EAX is clobbered -# d EDX is clobbered -# x both the source operands are clobbered (xchg) -# m sets an XMM reg -# -# flags:spec describe if the instruction uses or sets the flags (unused) -# -# s sets the flags -# u uses the flags -# m uses and modifies the flags -# -# res:spec describe what units are used in the processor (unused) -# -# delay: describe delay slots (unused) -# -# the required specifiers are: len, clob (if registers are clobbered), the registers -# specifiers if the registers are actually used, flags (when scheduling is implemented). -# -# See the code in mini-x86.c for more details on how the specifiers are used. -# -relaxed_nop: len:4 -break: len:4 -jmp: len:48 -br: len:4 -beq: len:4 -bge: len:4 -bgt: len:4 -ble: len:4 -blt: len:4 -bne.un: len:4 -bge.un: len:4 -bgt.un: len:4 -ble.un: len:4 -blt.un: len:4 -label: len:0 -add: dest:i src1:i src2:i len:4 -sub: dest:i src1:i src2:i len:4 -mul: dest:i src1:i src2:i len:4 -div: dest:a src1:a src2:i len:16 clob:d -div.un: dest:a src1:a src2:i len:16 clob:d -rem: dest:d src1:a src2:i len:16 clob:a -rem.un: dest:d src1:a src2:i len:16 clob:a -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: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 -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:24 -conv.r8: dest:f src1:i len:24 -conv.u4: dest:i src1:i len:4 -conv.u8: dest:i src1:i len:4 -conv.r.un: dest:f src1:i len:8 -throw: src1:i len:20 -rethrow: src1:i len:20 -conv.ovf.i4.un: dest:i src1:i len:16 -conv.ovf.u4.un: -conv.ovf.u4: dest:i src1:i len:15 -ckfinite: dest:f src1:f len:44 -conv.u2: dest:i src1:i len:4 -conv.u1: dest:i src1:i len:4 -conv.i: dest:i src1:i len:4 -mul.ovf: dest:i src1:i src2:i clob:1 len:10 -# this opcode is handled specially in the code generator -mul.ovf.un: dest:i src1:i src2:i len:18 -conv.u: dest:i src1:i len:4 -ceq: dest:c len:8 -cgt: dest:c len:8 -cgt.un: dest:c len:8 -clt: dest:c len:8 -clt.un: dest:c len:8 -localloc: dest:i src1:i src2:i len:40 clob:1 -compare: src1:i src2:i len:4 -lcompare: src1:i src2:i len:4 -icompare: src1:i src2:i len:4 -compare_imm: src1:i len:4 -icompare_imm: src1:i len:4 -fcompare: src1:f src2:f len:4 - -alpha_cmp_eq: src1:i src2:i len:4 -alpha_cmp_imm_eq: src1:i len:4 -alpha_cmp_ule: src1:i src2:i len:4 -alpha_cmp_imm_ule: src1:i len:4 -alpha_cmp_le: src1:i src2:i len:4 -alpha_cmp_imm_le: src1:i len:4 -alpha_cmp_lt: src1:i src2:i len:4 -alpha_cmp_imm_lt: src1:i len:4 -alpha_cmp_ult: src1:i src2:i len:4 -alpha_cmp_imm_ult: src1:i len:4 - -alpha_cmpt_un: src1:f src2:f len:4 -alpha_cmpt_un_su: src1:f src2:f len:4 -alpha_cmpt_eq: src1:f src2:f len:4 -alpha_cmpt_eq_su: src1:f src2:f len:4 -alpha_cmpt_lt: src1:f src2:f len:4 -alpha_cmpt_lt_su: src1:f src2:f len:4 -alpha_cmpt_le: src1:f src2:f len:4 -alpha_cmpt_le_su: src1:f src2:f len:4 - -oparglist: src1:b len:11 -setlret: dest:i src1:i src2:i len:4 -checkthis: src1:b len:4 -call: dest:a clob:c len:64 -voidcall: clob:c len:64 -voidcall_reg: src1:i clob:c len:64 -voidcall_membase: src1:b clob:c len:64 -fcall: dest:f len:64 clob:c -fcall_reg: dest:f src1:i len:64 clob:c -fcall_membase: dest:f src1:b len:64 clob:c -lcall: dest:a len:64 clob:c -lcall_reg: dest:a src1:i len:64 clob:c -lcall_membase: dest:a src1:b len:64 clob:c -vcall: len:64 clob:c -vcall_reg: src1:i len:64 clob:c -vcall_membase: src1:b len:64 clob:c -call_reg: dest:a src1:i len:64 clob:c -call_membase: dest:a src1:b len:64 clob:c -iconst: dest:i len:40 -i8const: dest:i len:40 -r4const: dest:f len:40 -r8const: dest:f len:40 -store_membase_imm: dest:b len:4 -store_membase_reg: dest:b src1:i len:4 -storei8_membase_reg: dest:b src1:i len:4 -storei1_membase_imm: dest:b len:4 -storei1_membase_reg: dest:b src1:c len:24 -storei2_membase_imm: dest:b len:4 -storei2_membase_reg: dest:b src1:i len:44 -storei4_membase_imm: dest:b len:4 -storei4_membase_reg: dest:b src1:i len:4 -storei8_membase_imm: dest:b len:4 -storer4_membase_reg: dest:b src1:f len:4 -storer8_membase_reg: dest:b src1:f len:4 -load_membase: dest:i src1:b len:4 -loadi1_membase: dest:c src1:b len:16 -loadu1_membase: dest:c src1:b len:12 -loadi2_membase: dest:i src1:b len:28 -loadu2_membase: dest:i src1:b len:24 -loadi4_membase: dest:i src1:b len:4 -loadu4_membase: dest:i src1:b len:8 -loadi8_membase: dest:i src1:b len:4 -loadr4_membase: dest:f src1:b len:4 -loadr8_membase: dest:f src1:b len:4 -loadu4_mem: dest:i len:4 -# amd64_loadi8_memindex: dest:i src1:i src2:i len:10 -move: dest:i src1:i len:4 -add_imm: dest:i src1:i len:4 -sub_imm: dest:i src1:i len:4 -mul_imm: dest:i src1:i len:11 -# there is no actual support for division or reminder by immediate -# we simulate them, though (but we need to change the burg rules -# to allocate a symbolic reg for src2) -div_imm: dest:a src1:i src2:i len:16 clob:d -div_un_imm: dest:a src1:i src2:i len:16 clob:d -rem_imm: dest:d src1:i src2:i len:16 clob:a -rem_un_imm: dest:d src1:i src2:i len:16 clob:a -and_imm: dest:i src1:i len:4 -or_imm: dest:i src1:i len:4 -xor_imm: dest:i src1:i len:4 -shl_imm: dest:i src1:i len:4 -shr_imm: dest:i src1:i len:8 -shr_un_imm: dest:i src1:i len:8 -cond_exc_eq: len:8 -cond_exc_ne_un: len:8 -cond_exc_lt: len:8 -cond_exc_lt_un: len:8 -cond_exc_gt: len:28 -cond_exc_gt_un: len:28 -cond_exc_ge: len:8 -cond_exc_ge_un: len:8 -cond_exc_le: len:8 -cond_exc_le_un: len:8 -cond_exc_ov: len:8 -cond_exc_no: len:8 -cond_exc_c: len:8 -cond_exc_nc: len:8 -cond_exc_iov: len:8 -cond_exc_ic: len:8 -long_mul: dest:i src1:i src2:i clob:1 len:4 -long_mul_imm: dest:i src1:i clob:1 len:12 -long_div: dest:a src1:a src2:i len:16 clob:d -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: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:24 -long_conv_to_r8: dest:f src1:i len:24 -long_conv_to_ovf_i: dest:i src1:i src2:i len:40 -long_mul_ovf: dest:i src1:i src2:i clob:1 len:16 -long_mul_ovf_un: dest:i src1:i src2:i len:22 -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 len:4 -float_beq: len:4 -float_bne_un: len:12 -float_blt: len:4 -float_blt_un: len:12 -float_bgt: len:4 -float_bgt_un: len:12 -float_bge: len:4 -float_bge_un: len:12 -float_ble: len:4 -float_ble_un: len:12 -float_add: dest:f src1:f src2:f len:8 -float_sub: dest:f src1:f src2:f len:8 -float_mul: dest:f src1:f src2:f len:5 -float_div: dest:f src1:f src2:f len:8 -float_div_un: dest:f src1:f src2:f len:8 -float_rem: dest:f src1:f src2:f len:19 -float_rem_un: dest:f src1:f src2:f len:19 -float_neg: dest:f src1:f len:23 -float_not: dest:f src1:f len:3 -float_conv_to_i1: dest:i src1:f len:49 -float_conv_to_i2: dest:i src1:f len:49 -float_conv_to_i4: dest:i src1:f len:49 -float_conv_to_i8: dest:i src1:f len:49 -float_conv_to_u4: dest:i src1:f len:49 -float_conv_to_u8: dest:i src1:f len:49 -float_conv_to_u2: dest:i src1:f len:49 -float_conv_to_u1: dest:i src1:f len:49 -float_conv_to_i: dest:i src1:f len:49 -float_conv_to_ovf_i: dest:a src1:f len:40 -float_conv_to_ovd_u: dest:a src1:f len:40 -float_conv_to_r4: dest:f src1:f len:8 -float_conv_to_r8: dest:f src1:f len:8 -float_mul_ovf: -float_ceq: dest:i src1:f src2:f len:35 -float_cgt: dest:i src1:f src2:f len:35 -float_cgt_un: dest:i src1:f src2:f len:48 -float_clt: dest:i src1:f src2:f len:35 -float_clt_un: dest:i src1:f src2:f len:42 -float_ceq_membase: dest:i src1:f src2:b len:35 -float_cgt_membase: dest:i src1:f src2:b len:35 -float_cgt_un_membase: dest:i src1:f src2:b len:48 -float_clt_membase: dest:i src1:f src2:b len:35 -float_clt_un_membase: dest:i src1:f src2:b len:42 -float_conv_to_u: dest:i src1:f len:46 -fmove: dest:f src1:f len:8 -call_handler: len:4 clob:c -start_handler: len:96 -endfinally: len:96 -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 -# x86_compare_membase_imm: src1:b len:13 -# x86_compare_reg_membase: src1:i src2:b len:8 -# x86_inc_reg: dest:i src1:i clob:1 len:3 -# x86_inc_membase: src1:b len:8 -# x86_dec_reg: dest:i src1:i clob:1 len:3 -# x86_dec_membase: src1:b len:8 -# x86_add_membase_imm: src1:b len:13 -# x86_sub_membase_imm: src1:b len:13 -# x86_push: src1:i len:3 -# x86_push_imm: len:6 -# x86_push_membase: src1:b len:8 -# x86_push_obj: src1:b len:40 -# x86_lea: dest:i src1:i src2:i len:8 -# x86_lea_membase: dest:i src1:i len:11 -# x86_xchg: src1:i src2:i clob:x len:2 -# x86_fpop: src1:f len:3 -# x86_fp_load_i8: dest:f src1:b len:8 -# x86_fp_load_i4: dest:f src1:b len:8 -# x86_seteq_membase: src1:b len:9 -# x86_add_membase: dest:i src1:i src2:b clob:1 len:13 -# x86_sub_membase: dest:i src1:i src2:b clob:1 len:13 -# x86_mul_membase: dest:i src1:i src2:b clob:1 len:14 -tls_get: dest:i len:13 -# amd64_test_null: src1:i len:5 -# amd64_icompare_membase_reg: src1:b src2:i len:8 -# amd64_icompare_membase_imm: src1:b len:13 -# amd64_icompare_reg_membase: src1:i src2:b len:8 -# amd64_set_xmmreg_r4: dest:f src1:f len:14 clob:m -# amd64_set_xmmreg_r8: dest:f src1:f len:14 clob:m -atomic_add_i4: src1:b src2:i dest:i len:32 -atomic_add_new_i4: src1:b src2:i dest:i len:32 -atomic_exchange_i4: src1:b src2:i dest:i len:32 -atomic_add_i8: src1:b src2:i dest:i len:32 -atomic_add_new_i8: src1:b src2:i dest:i len:32 -atomic_exchange_i8: src1:b src2:i dest:i len:32 -memory_barrier: len:16 -alpha_trapb: len:4 -adc: dest:i src1:i src2:i len:3 clob:1 -addcc: dest:i src1:i src2:i len:28 -subcc: dest:i src1:i src2:i len:28 -adc_imm: dest:i src1:i len:8 clob:1 -sbb: dest:i src1:i src2:i len:3 clob:1 -sbb_imm: dest:i src1:i len:8 clob:1 -br_reg: src1:i len:4 -sin: dest:f src1:f len:32 -cos: dest:f src1:f len:32 -abs: dest:f src1:f len:4 -tan: dest:f src1:f len:59 -atan: dest:f src1:f len:9 -sqrt: dest:f src1:f len:32 -bigmul: len:3 dest:i src1:a src2:i -bigmul_un: len:3 dest:i src1:a src2:i -sext_i1: dest:i src1:i len:8 -sext_i2: dest:i src1:i len:8 -sext_i4: dest:i src1:i len:8 - -# 32 bit opcodes -# FIXME: fix sizes -int_add: dest:i src1:i src2:i len:4 -int_sub: dest:i src1:i src2:i len:4 -int_mul: dest:i src1:i src2:i clob:1 len:64 -int_mul_ovf: dest:i src1:i src2:i clob:1 len:64 -int_mul_ovf_un: dest:i src1:i src2:i clob:1 len:64 -int_div: dest:a src1:a src2:i clob:d len:64 -int_div_un: dest:a src1:a src2:i clob:d len:64 -int_rem: dest:d src1:a src2:i clob:a len:64 -int_rem_un: dest:d src1:a src2:i clob:a len:64 -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:i len:8 -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 -int_sbb_imm: dest:i src1:i clob:1 len:64 -int_addcc: dest:i src1:i src2:i len:28 -int_subcc: dest:i src1:i src2:i len:28 -int_add_imm: dest:i src1:i len:4 -int_sub_imm: dest:i src1:i len:4 -int_mul_imm: dest:i src1:i clob:1 len:64 -int_div_imm: dest:a src1:i clob:d len:64 -int_div_un_imm: dest:a src1:i clob:d len:64 -int_rem_imm: dest:d src1:i clob:a len:64 -int_rem_un_imm: dest:d src1:i clob:a len:64 -int_and_imm: dest:i src1:i len:4 -int_or_imm: dest:i src1:i len:4 -int_xor_imm: dest:i src1:i len:4 -int_shl_imm: dest:i src1:i len:8 -int_shr_imm: dest:i src1:i len:8 -int_shr_un_imm: dest:i src1:i len:8 -int_neg: dest:i src1:i len:4 -int_not: dest:i src1:i len:4 -int_ceq: dest:c len:64 -int_cgt: dest:c len:64 -int_cgt_un: dest:c len:64 -int_clt: dest:c len:8 -int_clt_un: dest:c len:8 -int_beq: len:4 -int_bne_un: len:4 -int_blt: len:4 -int_blt_un: len:4 -int_bgt: len:4 -int_bgt_un: len:4 -int_bge: len:4 -int_bge_un: len:4 -int_ble: len:4 -int_ble_un: len:4 - diff --git a/mono/mini/exceptions-alpha.c b/mono/mini/exceptions-alpha.c deleted file mode 100644 index f507f757210..00000000000 --- a/mono/mini/exceptions-alpha.c +++ /dev/null @@ -1,997 +0,0 @@ -/*------------------------------------------------------------------*/ -/* */ -/* Name - exceptions-alpha.c */ -/* */ -/* Function - Exception support for Alpha. */ -/* */ -/* Name - Sergey Tikhonov (tsv@solvo.ru) */ -/* */ -/* Date - January, 2006 */ -/* */ -/* Derivation - From exceptions-amd64 & exceptions-ia64 */ -/* Paolo Molaro (lupus@ximian.com) */ -/* Dietmar Maurer (dietmar@ximian.com) */ -/* Zoltan Varga (vargaz@gmail.com) */ -/* */ -/* */ -/*------------------------------------------------------------------*/ - -/*------------------------------------------------------------------*/ -/* D e f i n e s */ -/*------------------------------------------------------------------*/ -#define ALPHA_DEBUG(x) \ - if (mini_alpha_verbose_level) \ - g_debug ("ALPHA_DEBUG: %s is called.", x); - -#define ALPHA_PRINT if (mini_alpha_verbose_level) - -#define SZ_THROW 384 - -extern int mini_alpha_verbose_level; - -/*========================= End of Defines =========================*/ - - -/*------------------------------------------------------------------*/ -/* I n c l u d e s */ -/*------------------------------------------------------------------*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "mini.h" -#include "mini-alpha.h" - -/*========================= End of Includes ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_get_call_filter */ -/* */ -/* Function - Return a pointer to a method which calls an */ -/* exception filter. We also use this function to */ -/* call finally handlers (we pass NULL as @exc */ -/* object in this case). */ -/* */ -/*------------------------------------------------------------------*/ - -gpointer -mono_arch_get_call_filter (void) -{ - static gboolean inited = FALSE; - static unsigned int *start_code; - unsigned int *code; - - ALPHA_DEBUG("mono_arch_get_call_filter"); - - if (inited) - return start_code; - - start_code = code = mono_global_codeman_reserve (128 * 4); - - /* call_filter (MonoContext *ctx, unsigned long eip) */ - code = start_code; - - alpha_ldah( code, alpha_gp, alpha_pv, 0 ); - alpha_lda( code, alpha_gp, alpha_gp, 0 ); // ldgp gp, 0(pv) - - /* store call convention parameters on stack */ - alpha_lda(code, alpha_sp, alpha_sp, -(8*25)); // Save 22 regs + RA, FP - alpha_stq(code, alpha_ra, alpha_sp, 0); - alpha_stq(code, alpha_fp, alpha_sp, 8); - - /* set the frame pointer */ - alpha_mov1( code, alpha_sp, alpha_fp ); - - /* Save registers */ - alpha_stq(code, alpha_r1, alpha_fp, (16+(8*0))); - alpha_stq(code, alpha_r2, alpha_fp, (16+(8*1))); - alpha_stq(code, alpha_r3, alpha_fp, (16+(8*2))); - alpha_stq(code, alpha_r4, alpha_fp, (16+(8*3))); - alpha_stq(code, alpha_r5, alpha_fp, (16+(8*4))); - alpha_stq(code, alpha_r6, alpha_fp, (16+(8*5))); - alpha_stq(code, alpha_r7, alpha_fp, (16+(8*6))); - alpha_stq(code, alpha_r8, alpha_fp, (16+(8*7))); - alpha_stq(code, alpha_r9, alpha_fp, (16+(8*8))); - alpha_stq(code, alpha_r10, alpha_fp, (16+(8*9))); - alpha_stq(code, alpha_r11, alpha_fp, (16+(8*10))); - alpha_stq(code, alpha_r12, alpha_fp, (16+(8*11))); - alpha_stq(code, alpha_r13, alpha_fp, (16+(8*12))); - alpha_stq(code, alpha_r14, alpha_fp, (16+(8*13))); - alpha_stq(code, alpha_r22, alpha_fp, (16+(8*14))); - alpha_stq(code, alpha_r23, alpha_fp, (16+(8*15))); - alpha_stq(code, alpha_r24, alpha_fp, (16+(8*16))); - alpha_stq(code, alpha_r25, alpha_fp, (16+(8*17))); - alpha_stq(code, alpha_r26, alpha_fp, (16+(8*18))); - alpha_stq(code, alpha_r27, alpha_fp, (16+(8*19))); - alpha_stq(code, alpha_r28, alpha_fp, (16+(8*20))); - alpha_stq(code, alpha_r29, alpha_fp, (16+(8*21))); - - /* Load regs from ctx */ - - alpha_ldq(code, alpha_r1, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r1])); - alpha_ldq(code, alpha_r2, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r2])); - alpha_ldq(code, alpha_r3, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r3])); - alpha_ldq(code, alpha_r4, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r4])); - alpha_ldq(code, alpha_r5, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r5])); - alpha_ldq(code, alpha_r6, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r6])); - alpha_ldq(code, alpha_r7, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r7])); - alpha_ldq(code, alpha_r8, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r8])); - alpha_ldq(code, alpha_r9, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r9])); - alpha_ldq(code, alpha_r10, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r10])); - alpha_ldq(code, alpha_r11, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r11])); - alpha_ldq(code, alpha_r12, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r12])); - alpha_ldq(code, alpha_r13, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r13])); - alpha_ldq(code, alpha_r14, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r14])); - alpha_ldq(code, alpha_r15, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r15])); - alpha_ldq(code, alpha_r22, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r22])); - alpha_ldq(code, alpha_r23, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r23])); - alpha_ldq(code, alpha_r24, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r24])); - alpha_ldq(code, alpha_r25, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r25])); - alpha_ldq(code, alpha_r26, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r26])); - alpha_ldq(code, alpha_r27, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r27])); - alpha_ldq(code, alpha_r28, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r28])); - alpha_ldq(code, alpha_r29, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r29])); - - alpha_mov1(code, alpha_a1, alpha_pv); - - /* call the handler */ - alpha_jsr(code, alpha_ra, alpha_pv, 0); - - /* restore saved regs */ - alpha_ldq(code, alpha_r1, alpha_sp, (16+(8*0))); - alpha_ldq(code, alpha_r2, alpha_sp, (16+(8*1))); - alpha_ldq(code, alpha_r3, alpha_sp, (16+(8*2))); - alpha_ldq(code, alpha_r4, alpha_sp, (16+(8*3))); - alpha_ldq(code, alpha_r5, alpha_sp, (16+(8*4))); - alpha_ldq(code, alpha_r6, alpha_sp, (16+(8*5))); - alpha_ldq(code, alpha_r7, alpha_sp, (16+(8*6))); - alpha_ldq(code, alpha_r8, alpha_sp, (16+(8*7))); - alpha_ldq(code, alpha_r9, alpha_sp, (16+(8*8))); - alpha_ldq(code, alpha_r10, alpha_sp, (16+(8*9))); - alpha_ldq(code, alpha_r11, alpha_sp, (16+(8*10))); - alpha_ldq(code, alpha_r12, alpha_sp, (16+(8*11))); - alpha_ldq(code, alpha_r13, alpha_sp, (16+(8*12))); - alpha_ldq(code, alpha_r14, alpha_sp, (16+(8*13))); - alpha_ldq(code, alpha_r22, alpha_sp, (16+(8*14))); - alpha_ldq(code, alpha_r23, alpha_sp, (16+(8*15))); - alpha_ldq(code, alpha_r24, alpha_sp, (16+(8*16))); - alpha_ldq(code, alpha_r25, alpha_sp, (16+(8*17))); - alpha_ldq(code, alpha_r26, alpha_sp, (16+(8*18))); - alpha_ldq(code, alpha_r27, alpha_sp, (16+(8*19))); - alpha_ldq(code, alpha_r28, alpha_sp, (16+(8*20))); - alpha_ldq(code, alpha_r29, alpha_sp, (16+(8*21))); - - alpha_ldq(code, alpha_ra, alpha_sp, 0); - alpha_ldq(code, alpha_fp, alpha_sp, 8); - alpha_lda(code, alpha_sp, alpha_sp, (8*25)); // Save 22 regs + RA, FP - - alpha_ret(code, alpha_ra, 1); - - inited = TRUE; - - g_assert (( ((char *)code) - (char *)start_code) < 128 * 4); - - return start_code; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - arch_get_throw_exception */ -/* */ -/* Function - Return a function pointer which can be used to */ -/* raise exceptions. The returned function has the */ -/* following signature: */ -/* void (*func) (MonoException *exc); */ -/* */ -/*------------------------------------------------------------------*/ - -static void throw_exception(MonoException *exc, unsigned long RA, - unsigned long *SP, unsigned long rethrow) -{ - static void (*restore_context) (MonoContext *); - MonoContext ctx; - unsigned long *LSP = SP - 24; - - //g_print("ALPHA: throw_exception - Exc: %p, RA: %0lX, SP: %p\n", - // exc, RA, SP); - - if (!restore_context) - restore_context = mono_arch_get_restore_context (); - - // Save stored regs into context - ctx.uc_mcontext.sc_regs[alpha_r0] = LSP[0]; - ctx.uc_mcontext.sc_regs[alpha_r1] = LSP[1]; - ctx.uc_mcontext.sc_regs[alpha_r2] = LSP[2]; - ctx.uc_mcontext.sc_regs[alpha_r3] = LSP[3]; - ctx.uc_mcontext.sc_regs[alpha_r4] = LSP[4]; - ctx.uc_mcontext.sc_regs[alpha_r5] = LSP[5]; - ctx.uc_mcontext.sc_regs[alpha_r6] = LSP[6]; - ctx.uc_mcontext.sc_regs[alpha_r7] = LSP[7]; - ctx.uc_mcontext.sc_regs[alpha_r8] = LSP[8]; - ctx.uc_mcontext.sc_regs[alpha_r9] = LSP[9]; - ctx.uc_mcontext.sc_regs[alpha_r10] = LSP[10]; - ctx.uc_mcontext.sc_regs[alpha_r11] = LSP[11]; - ctx.uc_mcontext.sc_regs[alpha_r12] = LSP[12]; - ctx.uc_mcontext.sc_regs[alpha_r13] = LSP[13]; - ctx.uc_mcontext.sc_regs[alpha_r14] = LSP[14]; - ctx.uc_mcontext.sc_regs[alpha_r15] = LSP[15]; - ctx.uc_mcontext.sc_regs[alpha_r22] = LSP[16]; - ctx.uc_mcontext.sc_regs[alpha_r23] = LSP[17]; - ctx.uc_mcontext.sc_regs[alpha_r24] = LSP[18]; - ctx.uc_mcontext.sc_regs[alpha_r25] = LSP[19]; - ctx.uc_mcontext.sc_regs[alpha_r26] = LSP[20]; - ctx.uc_mcontext.sc_regs[alpha_r27] = LSP[21]; - ctx.uc_mcontext.sc_regs[alpha_r28] = LSP[22]; - ctx.uc_mcontext.sc_regs[alpha_r29] = LSP[23]; - - ctx.uc_mcontext.sc_regs[alpha_r30] = (unsigned long)SP; - ctx.uc_mcontext.sc_pc = RA; - - if (mono_object_isinst (exc, mono_defaults.exception_class)) - { - MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) - mono_ex->stack_trace = NULL; - } - - mono_handle_exception (&ctx, exc); - - restore_context(&ctx); - - g_assert_not_reached (); -} - -/* -** This trampoline code is called from the code as action on -** throw opcode. It should save all necessary regs somethere and -** call the C function to do the rest. -** For Alpha trampoline code should allocate space on stack and -** save all registers into it. Then call "throw_exception" -** function with "exc" info and saved registers. The "throw_exception" -** should handle the rest. The "throw_exception" has signature -** void (*throw_exception)(MonoException *, long PC, long SP) -** The stack layout is: -** R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, -** R15, R22, R23, R24, R25, R26, R27, R28, R29 -** -** -*/ - -static gpointer -get_throw_trampoline (gboolean rethrow) -{ - guint8 *start_code; - unsigned int *code; - - start_code = mono_global_codeman_reserve (46*4); - - code = (unsigned int *)start_code; - - /* 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 - alpha_mov1(code, alpha_zero, alpha_a3); - - alpha_lda(code, alpha_sp, alpha_sp, -(24*8)); // Allocate stack for regs - - alpha_stq(code, alpha_r0, alpha_sp, 0*8); - alpha_stq(code, alpha_r1, alpha_sp, 1*8); - alpha_stq(code, alpha_r2, alpha_sp, 2*8); - alpha_stq(code, alpha_r3, alpha_sp, 3*8); - alpha_stq(code, alpha_r4, alpha_sp, 4*8); - alpha_stq(code, alpha_r5, alpha_sp, 5*8); - alpha_stq(code, alpha_r6, alpha_sp, 6*8); - alpha_stq(code, alpha_r7, alpha_sp, 7*8); - alpha_stq(code, alpha_r8, alpha_sp, 8*8); - alpha_stq(code, alpha_r9, alpha_sp, 9*8); - alpha_stq(code, alpha_r10, alpha_sp, 10*8); - alpha_stq(code, alpha_r11, alpha_sp, 11*8); - alpha_stq(code, alpha_r12, alpha_sp, 12*8); - alpha_stq(code, alpha_r13, alpha_sp, 13*8); - alpha_stq(code, alpha_r14, alpha_sp, 14*8); - alpha_stq(code, alpha_r15, alpha_sp, 15*8); - alpha_stq(code, alpha_r22, alpha_sp, 16*8); - alpha_stq(code, alpha_r23, alpha_sp, 17*8); - alpha_stq(code, alpha_r24, alpha_sp, 18*8); - alpha_stq(code, alpha_r25, alpha_sp, 19*8); - alpha_stq(code, alpha_r26, alpha_sp, 20*8); - alpha_stq(code, alpha_r27, alpha_sp, 21*8); - alpha_stq(code, alpha_r28, alpha_sp, 22*8); - alpha_stq(code, alpha_r29, alpha_sp, 23*8); - - alpha_mov1(code, alpha_zero, alpha_pv); - alpha_lda(code, alpha_r1, alpha_zero, - ((unsigned long)throw_exception)&0xFFFF); - alpha_lda(code, alpha_r2, alpha_zero, - (((unsigned long)throw_exception) >> 16)&0xFFFF); - alpha_lda(code, alpha_r3, alpha_zero, - (((unsigned long)throw_exception) >> 32)&0xFFFF); - alpha_lda(code, alpha_r4, alpha_zero, - (((unsigned long)throw_exception) >> 48)&0xFFFF); - alpha_zapnot_(code, alpha_r1, 0x3, alpha_r1); - alpha_bis(code, alpha_r1, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r2, 0x3, alpha_r2); - alpha_sll_(code, alpha_r2, 16, alpha_r2); - alpha_bis(code, alpha_r2, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r3, 0x3, alpha_r3); - alpha_sll_(code, alpha_r3, 32, alpha_r3); - alpha_bis(code, alpha_r3, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r4, 0x3, alpha_r4); - alpha_sll_(code, alpha_r4, 48, alpha_r4); - alpha_bis(code, alpha_r4, alpha_pv, alpha_pv); // pv - handle_exception addr - - alpha_jmp(code, alpha_zero, alpha_pv, 0); - - // alpha_break(code); - - g_assert (( ((char *)code) - (char *)start_code) < 46 * 4); - - return start_code; -} - -/** - * mono_arch_get_throw_exception: - * - * Returns a function pointer which can be used to raise - * exceptions. The returned function has the following - * signature: void (*func) (MonoException *exc); - * - */ -gpointer -mono_arch_get_throw_exception (void) -{ - static guint8* start; - static gboolean inited = FALSE; - - ALPHA_DEBUG("mono_arch_get_throw_exception"); - - if (inited) - return start; - - start = get_throw_trampoline (FALSE); - - inited = TRUE; - - return start; -} -/*========================= End of Function ========================*/ - - -/** - * mono_arch_get_throw_corlib_exception: - * - * Returns a function pointer which can be used to raise - * corlib exceptions. The returned function has the following - * signature: void (*func) (guint32 ex_token, guint32 offset); - * Here, offset is the offset which needs to be substracted from the caller IP - * to get the IP of the throw. Passing the offset has the advantage that it - * needs no relocations in the caller. - */ -gpointer -mono_arch_get_throw_corlib_exception (void) -{ - static guint8* start; - static gboolean inited = FALSE; - unsigned int *code; - guint64 throw_ex; - - ALPHA_DEBUG("mono_arch_get_throw_corlib_exception"); - - if (inited) - return start; - - start = mono_global_codeman_reserve (512); - - code = (unsigned int *)start; - // Logic - // Expect exception token as parameter - // call mono_exception_from_token(void *, uint32 token) - // Get result and call "throw_ex" (got from mono_arch_get_throw_exception) - // Throw exception - - // The trampoline code will be called with PV set - // so expect correct ABI handling - - //alpha_ldah(code, alpha_gp, alpha_pv, 0); - //alpha_lda(code, alpha_gp, alpha_gp, 0); - alpha_lda(code, alpha_sp, alpha_sp, -(8*4)); - - // Save caller GP - alpha_stq(code, alpha_gp, alpha_sp, 24); - - /* store call convention parameters on stack */ - alpha_stq( code, alpha_ra, alpha_sp, 0 ); // ra - alpha_stq( code, alpha_fp, alpha_sp, 8 ); // fp - - /* set the frame pointer */ - alpha_mov1(code, alpha_sp, alpha_fp ); - - // Store throw_ip offset - alpha_stq(code, alpha_a1, alpha_fp, 16); - - // Prepare to call "mono_exception_from_token (MonoImage *image, guint32 token)" - // Move token to a1 reg - alpha_mov1(code, alpha_a0, alpha_a1); - - alpha_mov1(code, alpha_zero, alpha_a0); - alpha_lda(code, alpha_r1, alpha_zero, - ((unsigned long)mono_defaults.exception_class->image)&0xFFFF); - alpha_lda(code, alpha_r2, alpha_zero, - (((unsigned long)mono_defaults.exception_class->image) >> 16)&0xFFFF); - alpha_lda(code, alpha_r3, alpha_zero, - (((unsigned long)mono_defaults.exception_class->image) >> 32)&0xFFFF); - alpha_lda(code, alpha_r4, alpha_zero, - (((unsigned long)mono_defaults.exception_class->image) >> 48)&0xFFFF); - alpha_zapnot_(code, alpha_r1, 0x3, alpha_r1); - alpha_bis(code, alpha_r1, alpha_a0, alpha_a0); - - alpha_zapnot_(code, alpha_r2, 0x3, alpha_r2); - alpha_sll_(code, alpha_r2, 16, alpha_r2); - alpha_bis(code, alpha_r2, alpha_a0, alpha_a0); - - alpha_zapnot_(code, alpha_r3, 0x3, alpha_r3); - alpha_sll_(code, alpha_r3, 32, alpha_r3); - alpha_bis(code, alpha_r3, alpha_a0, alpha_a0); - - alpha_zapnot_(code, alpha_r4, 0x3, alpha_r4); - alpha_sll_(code, alpha_r4, 48, alpha_r4); - alpha_bis(code, alpha_r4, alpha_a0, alpha_a0); // a0 - mono_defaults.exception_class->image - - alpha_mov1(code, alpha_zero, alpha_pv); - alpha_lda(code, alpha_r1, alpha_zero, - ((unsigned long)mono_exception_from_token)&0xFFFF); - alpha_lda(code, alpha_r2, alpha_zero, - (((unsigned long)mono_exception_from_token) >> 16)&0xFFFF); - alpha_lda(code, alpha_r3, alpha_zero, - (((unsigned long)mono_exception_from_token) >> 32)&0xFFFF); - alpha_lda(code, alpha_r4, alpha_zero, - (((unsigned long)mono_exception_from_token) >> 48)&0xFFFF); - alpha_zapnot_(code, alpha_r1, 0x3, alpha_r1); - alpha_bis(code, alpha_r1, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r2, 0x3, alpha_r2); - alpha_sll_(code, alpha_r2, 16, alpha_r2); - alpha_bis(code, alpha_r2, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r3, 0x3, alpha_r3); - alpha_sll_(code, alpha_r3, 32, alpha_r3); - alpha_bis(code, alpha_r3, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r4, 0x3, alpha_r4); - alpha_sll_(code, alpha_r4, 48, alpha_r4); - alpha_bis(code, alpha_r4, alpha_pv, alpha_pv); // pv - mono_exception_from_token addr - - alpha_jsr(code, alpha_ra, alpha_pv, 0); - - // R0 holds pointer to initialised exception object - - throw_ex = (guint64)mono_arch_get_throw_exception (); - - alpha_mov1(code, alpha_r0, alpha_a0); - - // Calc return address - alpha_mov1(code, alpha_fp, alpha_sp); - alpha_ldq(code, alpha_ra, alpha_sp, 0); - alpha_ldq(code, alpha_fp, alpha_sp, 8); - alpha_ldq(code, alpha_a1, alpha_sp, 16); - alpha_addq(code, alpha_ra, alpha_a1, alpha_ra); - alpha_ldq(code, alpha_gp, alpha_sp, 24); - - // Modify stack to point to exception caller - alpha_lda(code, alpha_sp, alpha_sp, (8*4)); - - alpha_mov1(code, alpha_zero, alpha_pv); - alpha_lda(code, alpha_r1, alpha_zero, - ((unsigned long)throw_ex)&0xFFFF); - alpha_lda(code, alpha_r2, alpha_zero, - (((unsigned long)throw_ex) >> 16)&0xFFFF); - alpha_lda(code, alpha_r3, alpha_zero, - (((unsigned long)throw_ex) >> 32)&0xFFFF); - alpha_lda(code, alpha_r4, alpha_zero, - (((unsigned long)throw_ex) >> 48)&0xFFFF); - alpha_zapnot_(code, alpha_r1, 0x3, alpha_r1); - alpha_bis(code, alpha_r1, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r2, 0x3, alpha_r2); - alpha_sll_(code, alpha_r2, 16, alpha_r2); - alpha_bis(code, alpha_r2, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r3, 0x3, alpha_r3); - alpha_sll_(code, alpha_r3, 32, alpha_r3); - alpha_bis(code, alpha_r3, alpha_pv, alpha_pv); - - alpha_zapnot_(code, alpha_r4, 0x3, alpha_r4); - alpha_sll_(code, alpha_r4, 48, alpha_r4); - alpha_bis(code, alpha_r4, alpha_pv, alpha_pv); // pv - handle_exception addr - - alpha_jmp(code, alpha_zero, alpha_pv, 0); - - g_assert (((char *)code - (char *)start) < 512); - - inited = TRUE; - - return start; -} - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_handle_exception */ -/* */ -/* Function - Handle an exception raised by the JIT code. */ -/* */ -/* Parameters - ctx - Saved processor state */ -/* obj - The exception object */ -/* */ -/*------------------------------------------------------------------*/ - -gboolean -mono_arch_handle_exception (void *uc, gpointer obj) -{ - ALPHA_DEBUG("mono_arch_handle_exception"); - - return mono_handle_exception (uc, obj); -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_get_restore_context */ -/* */ -/* Function - Return the address of the routine that will rest- */ -/* ore the context. */ -/* */ -/*------------------------------------------------------------------*/ - -gpointer -mono_arch_get_restore_context () -{ - static guint8 *start_code = NULL; - static gboolean inited = FALSE; - unsigned int *code; - - ALPHA_DEBUG("mono_arch_get_restore_context"); - - if (inited) - return start_code; - - /* restore_contect (MonoContext *ctx) */ - - start_code = mono_global_codeman_reserve (30*4); - - code = (unsigned int *)start_code; - - alpha_ldq(code, alpha_r0, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r0])); - alpha_ldq(code, alpha_r1, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r1])); - alpha_ldq(code, alpha_r2, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r2])); - alpha_ldq(code, alpha_r3, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r3])); - alpha_ldq(code, alpha_r4, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r4])); - alpha_ldq(code, alpha_r5, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r5])); - alpha_ldq(code, alpha_r6, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r6])); - alpha_ldq(code, alpha_r7, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r7])); - alpha_ldq(code, alpha_r8, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r8])); - alpha_ldq(code, alpha_r9, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r9])); - alpha_ldq(code, alpha_r10, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r10])); - alpha_ldq(code, alpha_r11, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r11])); - alpha_ldq(code, alpha_r12, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r12])); - alpha_ldq(code, alpha_r13, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r13])); - alpha_ldq(code, alpha_r14, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r14])); - alpha_ldq(code, alpha_r15, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r15])); - alpha_ldq(code, alpha_r22, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r22])); - alpha_ldq(code, alpha_r23, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r23])); - alpha_ldq(code, alpha_r24, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r24])); - alpha_ldq(code, alpha_r25, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r25])); - alpha_ldq(code, alpha_r26, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r26])); - alpha_ldq(code, alpha_r27, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r27])); - alpha_ldq(code, alpha_r28, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r28])); - alpha_ldq(code, alpha_r29, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r29])); - alpha_ldq(code, alpha_r30, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_regs[alpha_r30])); - - alpha_ldq(code, alpha_ra, alpha_a0, - G_STRUCT_OFFSET(MonoContext, uc_mcontext.sc_pc)); - - alpha_ret(code, alpha_ra, 1); - - inited = TRUE; - - return start_code; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_ip_from_context */ -/* */ -/* Function - Return the instruction pointer from the context. */ -/* */ -/* Parameters - sigctx - Saved processor state */ -/* */ -/*------------------------------------------------------------------*/ - -gpointer -mono_arch_ip_from_context (void *sigctx) -{ - gpointer ip; - ALPHA_DEBUG("mono_arch_ip_from_context"); - - ip = (gpointer) MONO_CONTEXT_GET_IP(((MonoContext *) sigctx)); - - printf("ip_from_context = %p\n", ip); - - return ip; -} - - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - arch_get_rethrow_exception */ -/* */ -/* Function - Return a function pointer which can be used to */ -/* raise exceptions. The returned function has the */ -/* following signature: */ -/* void (*func) (MonoException *exc); */ -/* */ -/*------------------------------------------------------------------*/ - -gpointer -mono_arch_get_rethrow_exception (void) -{ - static guint8 *start; - static int inited = 0; - - ALPHA_DEBUG("mono_arch_get_rethrow_exception"); - - if (inited) - return start; - - start = get_throw_trampoline (TRUE); - - inited = 1; - - return start; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - arch_get_throw_exception_by_name */ -/* */ -/* Function - Return a function pointer which can be used to */ -/* raise corlib exceptions. The return function has */ -/* the following signature: */ -/* void (*func) (char *exc_name); */ -/* */ -/*------------------------------------------------------------------*/ - -gpointer -mono_arch_get_throw_exception_by_name (void) -{ - static guint8 *start; - static int inited = 0; - unsigned int *code; - - if (inited) - return start; - - start = mono_global_codeman_reserve (SZ_THROW); - // 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 ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_find_jit_info */ -/* */ -/* Function - This function is used to gather informatoin from */ -/* @ctx. It returns the MonoJitInfo of the corres- */ -/* ponding function, unwinds one stack frame and */ -/* stores the resulting context into @new_ctx. It */ -/* also stores a string describing the stack location*/ -/* into @trace (if not NULL), and modifies the @lmf */ -/* if necessary. @native_offset returns the IP off- */ -/* set from the start of the function or -1 if that */ -/* information is not available. */ -/* */ -/*------------------------------------------------------------------*/ - -MonoJitInfo * -mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, - MonoJitInfo *res, MonoJitInfo *prev_ji, - MonoContext *ctx, - MonoContext *new_ctx, MonoLMF **lmf, - mgreg_t **save_locations, - gboolean *managed) -{ - MonoJitInfo *ji; - int i; - gpointer ip = MONO_CONTEXT_GET_IP (ctx); - - ALPHA_DEBUG("mono_arch_find_jit_info"); - - /* Avoid costly table lookup during stack overflow */ - if (prev_ji && - (ip > prev_ji->code_start && - ((guint8*)ip < ((guint8*)prev_ji->code_start) + prev_ji->code_size))) - ji = prev_ji; - else - ji = mini_jit_info_table_find (domain, ip, NULL); - - if (managed) - *managed = FALSE; - - if (ji != NULL) - { - int offset; - gboolean omit_fp = 0; //(ji->used_regs & (1 << 31)) > 0; - - *new_ctx = *ctx; - - if (managed) - if (!ji->method->wrapper_type) - *managed = TRUE; - - /* - * Some managed methods like pinvoke wrappers might have save_lmf set. - * In this case, register save/restore code is not generated by the - * JIT, so we have to restore callee saved registers from the lmf. - */ - - if (ji->method->save_lmf) - { - /* - * We only need to do this if the exception was raised in managed - * code, since otherwise the lmf was already popped of the stack. - */ - if (*lmf && ((*lmf) != jit_tls->first_lmf) && - (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->rsp)) - { - new_ctx->uc_mcontext.sc_regs[alpha_fp] = (*lmf)->ebp; - new_ctx->uc_mcontext.sc_regs[alpha_sp] = (*lmf)->rsp; - new_ctx->uc_mcontext.sc_regs[alpha_gp] = (*lmf)->rgp; - - /* - new_ctx->rbp = (*lmf)->ebp; - new_ctx->rbx = (*lmf)->rbx; - new_ctx->rsp = (*lmf)->rsp; - new_ctx->r12 = (*lmf)->r12; - new_ctx->r13 = (*lmf)->r13; - new_ctx->r14 = (*lmf)->r14; - new_ctx->r15 = (*lmf)->r15; - */ - } - } - else - { - offset = omit_fp ? 0 : 2; - - /* restore caller saved registers */ - for (i = 0; i < MONO_MAX_IREGS; i++) - if (ALPHA_IS_CALLEE_SAVED_REG(i) && - (ji->used_regs & (1 << i))) - { - - guint64 reg; -#if 0 - if (omit_fp) - { - reg = *((guint64*)ctx->rsp + offset); - offset++; - } - else - { - //reg = *((guint64 *)ctx->SC_EBP + offset); - //offset--; - } - - switch (i) - { - case AMD64_RBX: - new_ctx->rbx = reg; - break; - case AMD64_R12: - new_ctx->r12 = reg; - break; - case AMD64_R13: - new_ctx->r13 = reg; - break; - case AMD64_R14: - new_ctx->r14 = reg; - break; - case AMD64_R15: - new_ctx->r15 = reg; - break; - case AMD64_RBP: - new_ctx->rbp = reg; - break; - default: - g_assert_not_reached (); - } -#endif - } - } - - if (*lmf && ((*lmf) != jit_tls->first_lmf) && - (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->rsp)) { - /* remove any unused lmf */ - *lmf = (*lmf)->previous_lmf; - } - -#if 0 - if (omit_fp) - { - /* Pop frame */ - new_ctx->rsp += (ji->used_regs >> 16) & (0x7fff); - new_ctx->SC_EIP = *((guint64 *)new_ctx->rsp) - 1; - /* Pop return address */ - new_ctx->rsp += 8; - } - else -#endif - { - - /* Pop FP and the RA */ - /* 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] & 0xFFFF)); - short ra_off = code[3] & 0xFFFF; - short fp_off = code[4] & 0xFFFF; - - /* Restore stack - value of FP reg + stack_size */ - new_ctx->uc_mcontext.sc_regs[alpha_sp] = - ctx->uc_mcontext.sc_regs[alpha_r15] + stack_size; - - /* 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] + ra_off)); - - /* Restore FP reg - @FP + 8 */ - new_ctx->uc_mcontext.sc_regs[alpha_r15] = - *((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 */ - code = (unsigned int *)new_ctx->uc_mcontext.sc_pc; - if ((code[0] & 0xFFFF0000) == 0x27ba0000 && // ldah gp,high_off(ra) - (code[1] & 0xFFFF0000) == 0x23bd0000) // lda gp,low_off(gp) - { - short high_off = (short)(code[0] & 0xFFFF); - short low_off = (short)(code[1] & 0xFFFF); - - long rgp = new_ctx->uc_mcontext.sc_pc + - (65536 * high_off) + low_off; - - new_ctx->uc_mcontext.sc_regs[alpha_gp] = rgp; - } - } - -#if 0 - /* Pop arguments off the stack */ - // No poping args off stack on Alpha - // We use fixed place - { - MonoJitArgumentInfo *arg_info = - g_newa (MonoJitArgumentInfo, - mono_method_signature (ji->method)->param_count + 1); - - guint32 stack_to_pop = - mono_arch_get_argument_info (mono_method_signature (ji->method), - mono_method_signature (ji->method)->param_count, - arg_info); - new_ctx->uc_mcontext.sc_regs[alpha_sp] += stack_to_pop; - } -#endif - return ji; - } - else if (*lmf) - { - // Unwind based on LMF info - if (!(*lmf)->method) - return (gpointer)-1; - - if ((ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->eip, NULL))) { - } else { - memset (res, 0, MONO_SIZEOF_JIT_INFO); - res->method = (*lmf)->method; - } - - new_ctx->uc_mcontext.sc_regs[alpha_fp] = (*lmf)->ebp; - new_ctx->uc_mcontext.sc_regs[alpha_sp] = (*lmf)->rsp; - new_ctx->uc_mcontext.sc_regs[alpha_gp] = (*lmf)->rgp; - new_ctx->uc_mcontext.sc_pc = (*lmf)->eip; - - *lmf = (*lmf)->previous_lmf; - - return ji ? ji : res; - } - - return NULL; -} - -/*========================= End of Function ========================*/ - - diff --git a/mono/mini/mini-alpha.c b/mono/mini/mini-alpha.c deleted file mode 100644 index 908b877f68f..00000000000 --- a/mono/mini/mini-alpha.c +++ /dev/null @@ -1,5887 +0,0 @@ -/*------------------------------------------------------------------*/ -/* */ -/* Name - mini-alpha.c */ -/* */ -/* Function - Alpha backend for the Mono code generator. */ -/* */ -/* Name - Sergey Tikhonov (tsv@solvo.ru) */ -/* */ -/* Date - January, 2006 */ -/* */ -/* Derivation - From mini-am64 & mini-ia64 & mini-s390 by - */ -/* Paolo Molaro (lupus@ximian.com) */ -/* Dietmar Maurer (dietmar@ximian.com) */ -/* Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */ -/* */ -/*------------------------------------------------------------------*/ - -/*------------------------------------------------------------------*/ -/* D e f i n e s */ -/*------------------------------------------------------------------*/ -#define ALPHA_DEBUG(x) \ - if (mini_alpha_verbose_level) \ - g_debug ("ALPHA_DEBUG: %s is called.", x); - -#define ALPHA_PRINT if (mini_alpha_verbose_level) - -#define NEW_INS(cfg,dest,op) do { \ - (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \ - (dest)->opcode = (op); \ - insert_after_ins (bb, last_ins, (dest)); \ -} while (0) - -#undef DEBUG -#define DEBUG(a) if (cfg->verbose_level > 1) a - -#define CFG_DEBUG(LVL) if (cfg->verbose_level > LVL) - -//#define ALPHA_IS_CALLEE_SAVED_REG(reg) (MONO_ARCH_CALLEE_SAVED_REGS & (1 << (reg))) -#define ALPHA_ARGS_REGS ((regmask_t)0x03F0000) -#define ARGS_OFFSET 16 - -#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) -#define alpha_is_imm(X) ((X >= 0 && X <= 255)) -#define ALPHA_LOAD_GP(IP) { AlphaGotData ge_data; add_got_entry(cfg, GT_LD_GTADDR, ge_data, IP, MONO_PATCH_INFO_NONE, 0); } - -/*========================= End of Defines =========================*/ - -/*------------------------------------------------------------------*/ -/* I n c l u d e s */ -/*------------------------------------------------------------------*/ - -#include "mini.h" -#include - -#include -#include -#include -#include - -#include "trace.h" -#include "mini-alpha.h" -#include "cpu-alpha.h" -#include "jit-icalls.h" - -/*========================= End of Includes ========================*/ - -/*------------------------------------------------------------------*/ -/* G l o b a l V a r i a b l e s */ -/*------------------------------------------------------------------*/ -static int indent_level = 0; - -int mini_alpha_verbose_level = 0; -static int bwx_supported = 0; - -static int appdomain_tls_offset = -1, - lmf_tls_offset = -1, - thread_tls_offset = -1; - -pthread_key_t lmf_addr_key; - -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); - -typedef enum { - ArgInIReg, - ArgInFloatReg, - ArgInDoubleReg, - ArgOnStack, - ArgValuetypeInReg, // ?? - ArgAggregate, - ArgNone -} ArgStorage; - - -typedef struct { - gint16 offset; - gint8 reg; - ArgStorage storage; - - /* Only if storage == ArgAggregate */ - int nregs, nslots; - //AggregateType atype; // So far use only AggregateNormal -} ArgInfo; - -typedef struct { - int nargs; - guint32 stack_usage; -// guint32 struct_ret; /// ??? - - guint32 reg_usage; - guint32 freg_usage; - gboolean need_stack_align; - - ArgInfo ret; - ArgInfo sig_cookie; - ArgInfo args [1]; -} CallInfo; - -static CallInfo* get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gboolean is_pinvoke); -static unsigned int *emit_call(MonoCompile *cfg, unsigned int *code, - guint32 patch_type, gconstpointer data); - -#define PARAM_REGS 6 -static int param_regs [] = -{ - alpha_a0, alpha_a1, - alpha_a2, alpha_a3, - alpha_a4, alpha_a5 -}; - -//static AMD64_Reg_No return_regs [] = { AMD64_RAX, AMD64_RDX }; - -static void inline -add_general (guint32 *gr, guint32 *stack_size, ArgInfo *ainfo) -{ - ainfo->offset = *stack_size; - - if (*gr >= PARAM_REGS) - { - ainfo->storage = ArgOnStack; - (*stack_size) += sizeof (gpointer); - } - else - { - ainfo->storage = ArgInIReg; - ainfo->reg = param_regs [*gr]; - (*gr) ++; - } -} - -#define FLOAT_PARAM_REGS 6 -static int fparam_regs [] = { alpha_fa0, alpha_fa1, alpha_fa2, alpha_fa3, - alpha_fa4, alpha_fa5 }; - -static void inline -add_float (guint32 *gr, guint32 *stack_size, ArgInfo *ainfo, - gboolean is_double) -{ - ainfo->offset = *stack_size; - - if (*gr >= FLOAT_PARAM_REGS) - { - ainfo->storage = ArgOnStack; - (*stack_size) += sizeof (gpointer); - } - else - { - /* A double register */ - if (is_double) - ainfo->storage = ArgInDoubleReg; - else - ainfo->storage = ArgInFloatReg; - - ainfo->reg = fparam_regs [*gr]; - (*gr) += 1; - } -} - -static void -add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, - gboolean is_return, - guint32 *gr, guint32 *fr, guint32 *stack_size) -{ - guint32 size; - MonoClass *klass; - MonoMarshalType *info; - //gboolean is_hfa = TRUE; - //guint32 hfa_type = 0; - - klass = mono_class_from_mono_type (type); - if (type->type == MONO_TYPE_TYPEDBYREF) - size = 3 * sizeof (gpointer); - else if (sig->pinvoke) - size = mono_type_native_stack_size (&klass->byval_arg, NULL); - else - size = mini_type_stack_size (gsctx, &klass->byval_arg, NULL); - - if (!sig->pinvoke || (size == 0) || is_return) { - /* Allways pass in memory */ - ainfo->offset = *stack_size; - *stack_size += ALIGN_TO (size, 8); - ainfo->storage = ArgOnStack; - - return; - } - - info = mono_marshal_load_type_info (klass); - g_assert (info); - - 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 - - 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 -// should determine which registers will be used to do the call -// For Alpha we could calculate number of parameter used for each -// call and allocate space in stack only for whose "a0-a5" registers -// that will be used in calls -static void -add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, MonoInst *arg, - ArgStorage storage, int reg, MonoInst *tree) -{ - switch (storage) - { - case ArgInIReg: - arg->opcode = OP_OUTARG_REG; - arg->inst_left = tree; - arg->inst_right = (MonoInst*)call; - arg->backend.reg3 = reg; - call->used_iregs |= 1 << reg; - break; - case ArgInFloatReg: - arg->opcode = OP_OUTARG_FREG; - arg->inst_left = tree; - arg->inst_right = (MonoInst*)call; - arg->backend.reg3 = reg; - call->used_fregs |= 1 << reg; - break; - case ArgInDoubleReg: - arg->opcode = OP_OUTARG_FREG; - arg->inst_left = tree; - arg->inst_right = (MonoInst*)call; - arg->backend.reg3 = reg; - call->used_fregs |= 1 << reg; - break; - default: - g_assert_not_reached (); - } -} - -static void -insert_after_ins (MonoBasicBlock *bb, MonoInst *ins, MonoInst *to_insert) -{ - if (ins == NULL) - { - ins = bb->code; - bb->code = to_insert; - to_insert->next = ins; - } - else - { - to_insert->next = ins->next; - ins->next = to_insert; - } -} - -static void add_got_entry(MonoCompile *cfg, AlphaGotType ge_type, - AlphaGotData ge_data, - int ip, MonoJumpInfoType type, gconstpointer target) -{ - AlphaGotEntry *AGE = mono_mempool_alloc (cfg->mempool, - sizeof (AlphaGotEntry)); - - AGE->type = ge_type; - - switch(ge_type) - { - case GT_INT: - AGE->value.data.i = ge_data.data.i; - break; - case GT_LONG: - AGE->value.data.l = ge_data.data.l; - break; - case GT_PTR: - AGE->value.data.p = ge_data.data.p; - break; - case GT_FLOAT: - AGE->value.data.f = ge_data.data.f; - break; - case GT_DOUBLE: - AGE->value.data.d = ge_data.data.d; - break; - case GT_LD_GTADDR: - AGE->value.data.l = ip; - break; - default: - AGE->type = GT_NONE; - } - - if (type != MONO_PATCH_INFO_NONE) - { - mono_add_patch_info(cfg, ip, type, target); - AGE->patch_info = cfg->patch_info; - } - else - AGE->patch_info = 0; - - if (AGE->type != GT_LD_GTADDR) - { - mono_add_patch_info(cfg, ip, MONO_PATCH_INFO_GOT_OFFSET, 0); - AGE->got_patch_info = cfg->patch_info; - } - - AGE->next = cfg->arch.got_data; - - cfg->arch.got_data = AGE; -} - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_create_vars */ -/* */ -/* Function - */ -/* */ -/* Returns - - * - * Params: - * cfg - pointer to compile unit - * - * TSV (guess) - * This method is called right before starting converting compiled - * method to IR. I guess we could find out how many arguments we - * should expect, what type and what return value would be. - * After that we could correct "cfg" structure, or "arch" part of - * that structure. - */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_create_vars (MonoCompile *cfg) -{ - MonoMethodSignature *sig; - CallInfo *cinfo; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_create_vars"); - - sig = mono_method_signature (cfg->method); - - cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE); - - if (cinfo->ret.storage == ArgValuetypeInReg) - cfg->ret_var_is_local = TRUE; - - g_free (cinfo); -} - - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_get_lmf_addr */ -/* */ -/* Function - */ -/* */ -/* Returns - */ -/* */ -/*------------------------------------------------------------------*/ - -gpointer -mono_arch_get_lmf_addr (void) -{ - ALPHA_DEBUG("mono_arch_get_lmf_addr"); - - return pthread_getspecific (lmf_addr_key); -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_free_jit_tls_data */ -/* */ -/* Function - Free tls data. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_free_jit_tls_data (MonoJitTlsData *tls) -{ - ALPHA_DEBUG("mono_arch_free_jit_tls_data"); -} - -/*========================= 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, *last_ins = NULL; - ins = bb->code; - - CFG_DEBUG(3) g_print ("ALPHA: PEEPHOLE_2 pass\n"); - - MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) { - switch (ins->opcode) - { - case OP_MOVE: - case OP_FMOVE: - /* - * Removes: - * - * OP_MOVE reg, reg except special case (mov at, at) - */ - if (ins->dreg == ins->sreg1 && - ins->dreg != alpha_at) - { - MONO_DELETE_INS (bb, ins); - continue; - } - - /* - * Removes: - * - * OP_MOVE sreg, dreg - * OP_MOVE dreg, sreg - */ - if (last_ins && last_ins->opcode == OP_MOVE && - ins->sreg1 == last_ins->dreg && - last_ins->dreg != alpha_at && - ins->dreg == last_ins->sreg1) - { - MONO_DELETE_INS (bb, ins); - continue; - } - - break; - case OP_MUL_IMM: - case OP_IMUL_IMM: - /* remove unnecessary multiplication with 1 */ - if (ins->inst_imm == 1) - { - if (ins->dreg != ins->sreg1) - { - ins->opcode = OP_MOVE; - } - else - { - MONO_DELETE_INS (bb, ins); - continue; - } - } - - break; - - case OP_LOADI8_MEMBASE: - case OP_LOAD_MEMBASE: - /* - * Note: if reg1 = reg2 the load op is removed - * - * OP_STOREI8_MEMBASE_REG reg1, offset(basereg) - * OP_LOADI8_MEMBASE offset(basereg), reg2 - * --> - * OP_STOREI8_MEMBASE_REG reg1, offset(basereg) - * OP_MOVE reg1, reg2 - */ - if (last_ins && - (last_ins->opcode == OP_STOREI8_MEMBASE_REG || - last_ins->opcode == OP_STORE_MEMBASE_REG) && - ins->inst_basereg == last_ins->inst_destbasereg && - ins->inst_offset == last_ins->inst_offset) - { - if (ins->dreg == last_ins->sreg1) - { - MONO_DELETE_INS (bb, ins); - continue; - } - else - { - //static int c = 0; printf ("MATCHX %s %d\n", cfg->method->name,c++); - ins->opcode = OP_MOVE; - ins->sreg1 = last_ins->sreg1; - } - } - break; - -#if 0 - case OP_LOAD_MEMBASE: - case OP_LOADI4_MEMBASE: - /* - * Note: if reg1 = reg2 the load op is removed - * - * OP_STORE_MEMBASE_REG reg1, offset(basereg) - * OP_LOAD_MEMBASE offset(basereg), reg2 - * --> - * OP_STORE_MEMBASE_REG reg1, offset(basereg) - * OP_MOVE reg1, reg2 - */ - if (last_ins && (last_ins->opcode == OP_STOREI4_MEMBASE_REG - /*|| last_ins->opcode == OP_STORE_MEMBASE_REG*/) && - ins->inst_basereg == last_ins->inst_destbasereg && - ins->inst_offset == last_ins->inst_offset) - { - if (ins->dreg == last_ins->sreg1) - { - MONO_DELETE_INS (bb, ins); - continue; - } - else - { - //static int c = 0; printf ("MATCHX %s %d\n", cfg->method->name,c++); - ins->opcode = OP_MOVE; - ins->sreg1 = last_ins->sreg1; - } - } - /* - * Note: reg1 must be different from the basereg in the second load - * Note: if reg1 = reg2 is equal then second load is removed - * - * OP_LOAD_MEMBASE offset(basereg), reg1 - * OP_LOAD_MEMBASE offset(basereg), reg2 - * --> - * OP_LOAD_MEMBASE offset(basereg), reg1 - * OP_MOVE reg1, reg2 - */ - - if (last_ins && (last_ins->opcode == OP_LOADI4_MEMBASE - || last_ins->opcode == OP_LOAD_MEMBASE) && - ins->inst_basereg != last_ins->dreg && - ins->inst_basereg == last_ins->inst_basereg && - ins->inst_offset == last_ins->inst_offset) - { - if (ins->dreg == last_ins->dreg) - { - MONO_DELETE_INS (bb, ins); - continue; - } - else - { - ins->opcode = OP_MOVE; - ins->sreg1 = last_ins->dreg; - } - - //g_assert_not_reached (); - } - break; -#endif - } - - last_ins = ins; - ins = ins->next; - } - - bb->last_ins = last_ins; -} - -// Convert to opposite branch opcode -static guint16 cvt_branch_opcode(guint16 opcode) -{ - switch (opcode) - { - case CEE_BEQ: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BEQ -> CEE_BNE_UN\n"); - return CEE_BNE_UN; - - - //case CEE_CGT_UN: - //printf("ALPHA: Branch cvt: CEE_CGT_UN -> OP_IBEQ\n"); - //return OP_IBEQ; - - //case OP_LCGT_UN: - //printf("ALPHA: Branch cvt: OP_LCGT_UN -> OP_IBEQ\n"); - //return OP_IBEQ; - - // case OP_CGT_UN: - //printf("ALPHA: Branch cvt: OP_CGT_UN -> OP_IBEQ\n"); - //return OP_IBEQ; - - case OP_IBEQ: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBEQ -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case OP_FBEQ: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_FBEQ -> OP_FBNE_UN\n"); - return OP_FBNE_UN; - - case OP_FBNE_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_FBNE_UN -> OP_FBEQ\n"); - return OP_FBEQ; - - case OP_IBNE_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBNE_UN -> OP_IBEQ\n"); - return OP_IBEQ; - - case CEE_BNE_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BNE_UN -> OP_IBEQ\n"); - return OP_IBEQ; - - case OP_IBLE: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBLE -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case OP_IBLE_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBLE_UN -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case CEE_BLE: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BLE -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case CEE_BLE_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BLE_UN -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case OP_IBLT: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBLT -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case CEE_BLT: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BLT -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case CEE_BLT_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BLT_UN -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case OP_IBLT_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBLT_UN -> OP_IBNE_UN\n"); - return OP_IBNE_UN; - - case OP_IBGE: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBGE -> OP_IBEQ\n"); - return OP_IBEQ; - - case CEE_BGE: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BGE -> OP_IBEQ\n"); - return OP_IBEQ; - - case CEE_BGT: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BGT -> OP_IBEQ\n"); - return OP_IBEQ; - - case OP_IBGT: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBGT -> OP_IBEQ\n"); - return OP_IBEQ; - - case CEE_BGT_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BGT_UN -> OP_IBEQ\n"); - return OP_IBEQ; - - case OP_IBGT_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBGT_UN -> OP_IBEQ\n"); - return OP_IBEQ; - - case CEE_BGE_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: CEE_BGE_UN -> OP_IBEQ\n"); - return OP_IBEQ; - - case OP_IBGE_UN: - ALPHA_PRINT g_debug("ALPHA: Branch cvt: OP_IBGE_UN -> OP_IBEQ\n"); - return OP_IBEQ; - - default: - break; - } - - ALPHA_PRINT g_debug("ALPHA: WARNING: No Branch cvt for: %d\n", opcode); - - return opcode; -} - -typedef enum { EQ, ULE, LE, LT, ULT } ALPHA_CMP_OPS; - -static guint16 cvt_cmp_opcode(guint16 opcode, ALPHA_CMP_OPS cond) -{ - guint16 ret_opcode; - - switch (opcode) - { - /* Use inssel-alpha.brg to handle cmp+b -> cmp+b cvt */ - case OP_FCOMPARE: - break; - - case OP_COMPARE: - case OP_ICOMPARE: - case OP_LCOMPARE: - { - switch(cond) - { - case EQ: - return OP_ALPHA_CMP_EQ; - case ULE: - return OP_ALPHA_CMP_ULE; - case LE: - return OP_ALPHA_CMP_LE; - case LT: - return OP_ALPHA_CMP_LT; - case ULT: - return OP_ALPHA_CMP_ULT; - } - } - break; - - case OP_ICOMPARE_IMM: - case OP_COMPARE_IMM: - { - switch(cond) - { - case EQ: - return OP_ALPHA_CMP_IMM_EQ; - case ULE: - return OP_ALPHA_CMP_IMM_ULE; - case LE: - return OP_ALPHA_CMP_IMM_LE; - case LT: - return OP_ALPHA_CMP_IMM_LT; - case ULT: - return OP_ALPHA_CMP_IMM_ULT; - } - } - } - - g_assert_not_reached(); - - return ret_opcode; -} - -static void cvt_cmp_branch(MonoInst *curr, MonoInst *next) -{ - // Instead of compare+b, - // Alpha has compare+br - // we need to convert - // Handle floating compare here too - - switch(next->opcode) - { - case CEE_BEQ: - case OP_IBEQ: - // Convert cmp + beq -> cmpeq + bne - curr->opcode = cvt_cmp_opcode(curr->opcode, EQ); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case OP_IBNE_UN: - case CEE_BNE_UN: - // cmp + ibne_un -> cmpeq + beq - curr->opcode = cvt_cmp_opcode(curr->opcode, EQ); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case OP_IBLE: - case CEE_BLE: - // cmp + ible -> cmple + bne, lcmp + ble -> cmple + bne - curr->opcode = cvt_cmp_opcode(curr->opcode, LE); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case CEE_BLE_UN: - case OP_IBLE_UN: - // cmp + ible_un -> cmpule + bne, lcmp + ble.un -> cmpule + bne - curr->opcode = cvt_cmp_opcode(curr->opcode, ULE); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case OP_IBLT: - case CEE_BLT: - // cmp + iblt -> cmplt + bne, lcmp + blt -> cmplt + bne - curr->opcode = cvt_cmp_opcode(curr->opcode, LT); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case CEE_BLT_UN: - case OP_IBLT_UN: - // lcmp + blt.un -> cmpult + bne - curr->opcode = cvt_cmp_opcode(curr->opcode, ULT); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case OP_IBGE: - case CEE_BGE: - // cmp + ibge -> cmplt + beq, lcmp + bge -> cmplt + beq - curr->opcode = cvt_cmp_opcode(curr->opcode, LT); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case CEE_BGE_UN: - case OP_IBGE_UN: - //lcmp + bge.un -> cmpult + beq - curr->opcode = cvt_cmp_opcode(curr->opcode, ULT); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case OP_IBGT: - case CEE_BGT: - // lcmp + bgt -> cmple + beq, cmp + ibgt -> cmple + beq - curr->opcode = cvt_cmp_opcode(curr->opcode, LE); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - case CEE_BGT_UN: - case OP_IBGT_UN: - // lcmp + bgt -> cmpule + beq, cmp + ibgt -> cmpule + beq - curr->opcode = cvt_cmp_opcode(curr->opcode, ULE); - next->opcode = cvt_branch_opcode(next->opcode); - break; - - // case CEE_CGT_UN: - case OP_CGT_UN: - case OP_ICGT_UN: - // cmp + cgt_un -> cmpule + beq - curr->opcode = cvt_cmp_opcode(curr->opcode, ULE); - break; - - case OP_ICEQ: - case OP_CEQ: - // cmp + iceq -> cmpeq + bne - curr->opcode = cvt_cmp_opcode(curr->opcode, EQ); - break; - - case OP_ICGT: - case OP_CGT: - // cmp + int_cgt -> cmple + beq - curr->opcode = cvt_cmp_opcode(curr->opcode, LE); - break; - - case OP_ICLT: - case OP_CLT: - // cmp + int_clt -> cmplt + bne - curr->opcode = cvt_cmp_opcode(curr->opcode, LT); - break; - - case OP_ICLT_UN: - case OP_CLT_UN: - // cmp + int_clt_un -> cmpult + bne - curr->opcode = cvt_cmp_opcode(curr->opcode, ULT); - break; - - - // The conditional exceptions will be handled in - // output_basic_blocks. Here we just determine correct - // cmp - case OP_COND_EXC_GT: - curr->opcode = cvt_cmp_opcode(curr->opcode, LE); - break; - - case OP_COND_EXC_GT_UN: - curr->opcode = cvt_cmp_opcode(curr->opcode, ULE); - break; - - case OP_COND_EXC_LT: - curr->opcode = cvt_cmp_opcode(curr->opcode, LT); - break; - - case OP_COND_EXC_LT_UN: - curr->opcode = cvt_cmp_opcode(curr->opcode, ULT); - break; - - case OP_COND_EXC_LE_UN: - curr->opcode = cvt_cmp_opcode(curr->opcode, ULE); - break; - - case OP_COND_EXC_NE_UN: - curr->opcode = cvt_cmp_opcode(curr->opcode, EQ); - break; - - case OP_COND_EXC_EQ: - curr->opcode = cvt_cmp_opcode(curr->opcode, EQ); - break; - - - default: - g_warning("cvt_cmp_branch called with %s(%0X) br opcode", - mono_inst_name(next->opcode), next->opcode); - - // g_assert_not_reached(); - - break; - } -} - - -/* - * mono_arch_lowering_pass: - * - * Converts complex opcodes into simpler ones so that each IR instruction - * corresponds to one machine instruction. - */ -void -mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) -{ - MonoInst *ins, *n, *temp, *last_ins = NULL; - MonoInst *next; - - ins = bb->code; - - /* - * FIXME: Need to add more instructions, but the current machine - * description can't model some parts of the composite instructions like - * cdq. - */ - - MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) { - switch (ins->opcode) - { - case OP_DIV_IMM: - case OP_REM_IMM: - case OP_IDIV_IMM: - case OP_IREM_IMM: - case OP_MUL_IMM: - NEW_INS (cfg, temp, OP_I8CONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - - switch (ins->opcode) - { - case OP_MUL_IMM: - ins->opcode = CEE_MUL; - break; - case OP_DIV_IMM: - ins->opcode = OP_LDIV; - break; - case OP_REM_IMM: - ins->opcode = OP_LREM; - break; - case OP_IDIV_IMM: - ins->opcode = OP_IDIV; - break; - case OP_IREM_IMM: - ins->opcode = OP_IREM; - break; - } - - ins->sreg2 = temp->dreg; - break; - - case OP_COMPARE: - case OP_ICOMPARE: - case OP_LCOMPARE: - case OP_FCOMPARE: - { - // Instead of compare+b/fcompare+b, - // Alpha has compare+br/fcompare+br - // we need to convert - next = ins->next; - - cvt_cmp_branch(ins, next); - } - break; - - case OP_COMPARE_IMM: - if (!alpha_is_imm (ins->inst_imm)) - { - NEW_INS (cfg, temp, OP_I8CONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - ins->opcode = OP_COMPARE; - ins->sreg2 = temp->dreg; - - // We should try to reevaluate new IR opcode - //continue; - } - - next = ins->next; - - cvt_cmp_branch(ins, next); - - break; - - case OP_ICOMPARE_IMM: - if (!alpha_is_imm (ins->inst_imm)) - { - NEW_INS (cfg, temp, OP_ICONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - ins->opcode = OP_ICOMPARE; - ins->sreg2 = temp->dreg; - - // We should try to reevaluate new IR opcode - //continue; - } - - next = ins->next; - - cvt_cmp_branch(ins, next); - - break; - - case OP_STORE_MEMBASE_IMM: - case OP_STOREI8_MEMBASE_IMM: - if (ins->inst_imm != 0) - { - NEW_INS (cfg, temp, OP_I8CONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - ins->opcode = OP_STOREI8_MEMBASE_REG; - ins->sreg1 = temp->dreg; - } - break; - - case OP_STOREI4_MEMBASE_IMM: - if (ins->inst_imm != 0) - { - MonoInst *temp; - NEW_INS (cfg, temp, OP_ICONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - ins->opcode = OP_STOREI4_MEMBASE_REG; - ins->sreg1 = temp->dreg; - } - break; - - case OP_STOREI1_MEMBASE_IMM: - if (ins->inst_imm != 0 || !bwx_supported) - { - MonoInst *temp; - NEW_INS (cfg, temp, OP_ICONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - ins->opcode = OP_STOREI1_MEMBASE_REG; - ins->sreg1 = temp->dreg; - } - break; - - case OP_STOREI2_MEMBASE_IMM: - if (ins->inst_imm != 0 || !bwx_supported) - { - MonoInst *temp; - NEW_INS (cfg, temp, OP_ICONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - ins->opcode = OP_STOREI2_MEMBASE_REG; - ins->sreg1 = temp->dreg; - } - break; - - case OP_IADD_IMM: - case OP_ISUB_IMM: - case OP_IAND_IMM: - case OP_IOR_IMM: - case OP_IXOR_IMM: - case OP_ISHL_IMM: - case OP_ISHR_IMM: - case OP_ISHR_UN_IMM: - if (!alpha_is_imm(ins->inst_imm)) - { - MonoInst *temp; - NEW_INS (cfg, temp, OP_ICONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - - switch(ins->opcode) - { - case OP_IADD_IMM: - ins->opcode = OP_IADD; - break; - case OP_ISUB_IMM: - ins->opcode = OP_ISUB; - break; - case OP_IAND_IMM: - ins->opcode = OP_IAND; - break; - case OP_IOR_IMM: - ins->opcode = OP_IOR; - break; - case OP_IXOR_IMM: - ins->opcode = OP_IXOR; - break; - case OP_ISHL_IMM: - ins->opcode = OP_ISHL; - break; - case OP_ISHR_IMM: - ins->opcode = OP_ISHR; - break; - case OP_ISHR_UN_IMM: - ins->opcode = OP_ISHR_UN; - - default: - break; - } - - ins->sreg2 = temp->dreg; - } - break; - case OP_ADD_IMM: - case OP_AND_IMM: - case OP_SHL_IMM: - if (!alpha_is_imm(ins->inst_imm)) - { - MonoInst *temp; - NEW_INS (cfg, temp, OP_ICONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - - switch(ins->opcode) - { - case OP_ADD_IMM: - ins->opcode = CEE_ADD; - break; - case OP_ISUB_IMM: - ins->opcode = CEE_SUB; - break; - case OP_AND_IMM: - ins->opcode = CEE_AND; - break; - case OP_SHL_IMM: - ins->opcode = CEE_SHL; - break; - default: - break; - } - - ins->sreg2 = temp->dreg; - } - break; - case OP_LSHR_IMM: - if (!alpha_is_imm(ins->inst_imm)) - { - MonoInst *temp; - NEW_INS(cfg, temp, OP_ICONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - ins->sreg2 = temp->dreg; - ins->opcode = OP_LSHR; - } - break; - case OP_LSHL_IMM: - if (!alpha_is_imm(ins->inst_imm)) - { - MonoInst *temp; - NEW_INS(cfg, temp, OP_ICONST); - temp->inst_c0 = ins->inst_imm; - temp->dreg = mono_alloc_ireg (cfg); - ins->sreg2 = temp->dreg; - ins->opcode = OP_LSHL; - } - break; - - default: - break; - } - - last_ins = ins; - ins = ins->next; - } - - bb->last_ins = last_ins; - - bb->max_vreg = cfg->next_vreg; -} - -/*========================= End of Function ========================*/ - -#define AXP_GENERAL_REGS 6 -#define AXP_MIN_STACK_SIZE 24 - -/* A typical Alpha stack frame looks like this */ -/* -fun: // called from outside the module. - ldgp gp,0(pv) // load the global pointer -fun..ng: // called from inside the module. - lda sp, -SIZE( sp ) // grow the stack downwards. - - stq ra, 0(sp) // save the return address. - - stq s0, 8(sp) // callee-saved registers. - stq s1, 16(sp) // ... - - // Move the arguments to the argument registers... - - mov addr, pv // Load the callee address - jsr ra, (pv) // call the method. - ldgp gp, 0(ra) // restore gp - - // return value is in v0 - - ldq ra, 0(sp) // free stack frame - ldq s0, 8(sp) // restore callee-saved registers. - ldq s1, 16(sp) - ldq sp, 32(sp) // restore stack pointer - - ret zero, (ra), 1 // return. - -// min SIZE = 48 -// our call must look like this. - -call_func: - ldgp gp, 0(pv) -call_func..ng: - .prologue - lda sp, -SIZE(sp) // grow stack SIZE bytes. - stq ra, SIZE-48(sp) // store ra - stq fp, SIZE-40(sp) // store fp (frame pointer) - stq a0, SIZE-32(sp) // store args. a0 = func - stq a1, SIZE-24(sp) // a1 = retval - stq a2, SIZE-16(sp) // a2 = this - stq a3, SIZE-8(sp) // a3 = args - mov sp, fp // set frame pointer - mov pv, a0 // func - - .calling_arg_this - mov a1, a2 - - .calling_arg_6plus - ldq t0, POS(a3) - stq t0, 0(sp) - ldq t1, POS(a3) - stq t1, 8(sp) - ... SIZE-56 ... - - mov zero,a1 - mov zero,a2 - mov zero,a3 - mov zero,a4 - mov zero,a5 - - .do_call - jsr ra, (pv) // call func - ldgp gp, 0(ra) // restore gp. - mov v0, t1 // move return value into t1 - - .do_store_retval - ldq t0, SIZE-24(fp) // load retval into t2 - stl t1, 0(t0) // store value. - - .finished - mov fp,sp - ldq ra,SIZE-48(sp) - ldq fp,SIZE-40(sp) - lda sp,SIZE(sp) - ret zero,(ra),1 -*/ - -/* - * emit_load_volatile_arguments: - * - * Load volatile arguments from the stack to the original input registers. - * Required before a tail call. - */ -static unsigned int* -emit_load_volatile_arguments (MonoCompile *cfg, unsigned int *code) -{ - MonoMethod *method = cfg->method; - MonoMethodSignature *sig; - MonoInst *inst; - CallInfo *cinfo; - guint32 i; - - /* FIXME: Generate intermediate code instead */ - - sig = mono_method_signature (method); - - cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE); - - if (sig->ret->type != MONO_TYPE_VOID) { - if ((cinfo->ret.storage == ArgInIReg) && - (cfg->ret->opcode != OP_REGVAR)) - { - alpha_ldq(code, cinfo->ret.reg, cfg->ret->inst_basereg, - cfg->ret->inst_offset); - } - } - - for (i = 0; i < sig->param_count + sig->hasthis; ++i) - { - ArgInfo *ainfo = &cinfo->args [i]; - MonoInst *inst = cfg->args [i]; - - switch(ainfo->storage) - { - case ArgInIReg: - // We need to save all used a0-a5 params - //for (i=0; ireg_usage) - { - //alpha_stq(code, ainfo->reg, alpha_fp, offset); - alpha_ldq(code, ainfo->reg, inst->inst_basereg, inst->inst_offset); - - CFG_DEBUG(3) g_print("ALPHA: Saved int arg reg %d at offset: %0lx\n", - ainfo->reg, inst->inst_offset/*offset*/); - } - //} - break; - case ArgInDoubleReg: - case ArgInFloatReg: - // We need to save all used af0-af5 params - //for (i=0; ifreg_usage) - { - switch(cinfo->args[i].storage) - { - case ArgInFloatReg: - //alpha_sts(code, ainfo->reg, alpha_fp, offset); - alpha_lds(code, ainfo->reg, inst->inst_basereg, inst->inst_offset); - break; - case ArgInDoubleReg: - //alpha_stt(code, ainfo->reg, alpha_fp, offset); - alpha_ldt(code, ainfo->reg, inst->inst_basereg, inst->inst_offset); - break; - default: - ; - } - - CFG_DEBUG(3) g_print("ALPHA: Saved float arg reg %d at offset: %0lx\n", - ainfo->reg, /*offset*/inst->inst_offset); - } - } - } - g_free (cinfo); - - return code; -} - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_emit_prolog */ -/* */ -/* Function - Create the instruction sequence for a function */ -/* prolog. */ -/* - * How to handle consts and method addreses: - * For method we will allocate array of qword after method epiloge. - * These qword will hold readonly info to method to properly to run. - * For example: qword constants, method addreses - * GP will point to start of data. Offsets to the data will be equal - * to "address" of data - start of GP. (GP = 0 during method jiting). - * GP is easily calculated from passed PV (method start address). - * The patch will update GP loadings. - * The GOT section should be more than 32Kb. - * The patch code should put proper offset since the real position of - * qword array will be known after the function epiloge. - */ -/*------------------------------------------------------------------*/ - -guint8 * -mono_arch_emit_prolog (MonoCompile *cfg) -{ - MonoMethod *method = cfg->method; - MonoMethodSignature *sig = mono_method_signature (method); - //int alloc_size, code_size, max_offset, quad; - unsigned int *code; - CallInfo *cinfo; - int i, stack_size, offset; - gint32 lmf_offset = cfg->arch.lmf_offset; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_emit_prolog"); - - // FIXME: Use just one field to hold calculated stack size - cfg->arch.stack_size = stack_size = cfg->stack_offset; - cfg->arch.got_data = 0; - - cfg->code_size = 512; - - code = (unsigned int *)g_malloc(cfg->code_size); - cfg->native_code = (void *)code; - - // Emit method prolog - // Calculate GP from passed PV, allocate stack - ALPHA_LOAD_GP(0) - alpha_ldah( code, alpha_gp, alpha_pv, 0 ); - alpha_lda( code, alpha_gp, alpha_gp, 0 ); // ldgp gp, 0(pv) - alpha_lda( code, alpha_sp, alpha_sp, -(stack_size) ); - - offset = cfg->arch.params_stack_size; - - /* store call convention parameters on stack */ - alpha_stq( code, alpha_ra, alpha_sp, (offset + 0) ); // RA - alpha_stq( code, alpha_fp, alpha_sp, (offset + 8) ); // FP - - /* set the frame pointer */ - alpha_mov1( code, alpha_sp, alpha_fp ); - - /* Save LMF */ - if (method->save_lmf) - { - // Save IP - alpha_stq(code, alpha_pv, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, eip))); - // Save SP - alpha_stq(code, alpha_sp, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, rsp))); - // Save FP - alpha_stq(code, alpha_fp, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, ebp))); - // Save GP - alpha_stq(code, alpha_gp, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, rgp))); - - // Save method - alpha_stq(code, alpha_pv, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, method))); - } - - /* Save (global) regs */ - offset = cfg->arch.reg_save_area_offset; - - for (i = 0; i < MONO_MAX_IREGS; ++i) - if (ALPHA_IS_CALLEE_SAVED_REG (i) && - (cfg->used_int_regs & (1 << i)) && - !( ALPHA_ARGS_REGS & (1 << i)) ) - { - alpha_stq(code, i, alpha_fp, offset); - CFG_DEBUG(3) g_print("ALPHA: Saved caller reg %d at offset: %0x\n", - i, offset); - offset += 8; - } - - offset = cfg->arch.args_save_area_offset; - - cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE); - - if (sig->ret->type != MONO_TYPE_VOID) - { - if ((cinfo->ret.storage == ArgInIReg) && - (cfg->ret->opcode != OP_REGVAR)) - { - /* Save volatile arguments to the stack */ - alpha_stq(code, cinfo->ret.reg, cfg->ret->inst_basereg, - cfg->ret->inst_offset); - } - } - - /* Keep this in sync with emit_load_volatile_arguments */ - for (i = 0; i < sig->param_count + sig->hasthis; ++i) - { - ArgInfo *ainfo = &cinfo->args [i]; - MonoInst *inst = cfg->args [i]; - int j; - - switch(ainfo->storage) - { - case ArgInIReg: - // We need to save all used a0-a5 params - { - if (inst->opcode == OP_REGVAR) - { - alpha_mov1(code, ainfo->reg, inst->dreg); - CFG_DEBUG(3) g_print("ALPHA: Saved int arg reg %d in reg %d\n", - ainfo->reg, inst->dreg); - } - else - { - alpha_stq(code, ainfo->reg, inst->inst_basereg, - inst->inst_offset); - - CFG_DEBUG(3) g_print("ALPHA: Saved int arg reg %d at offset: %0lx\n", - ainfo->reg, inst->inst_offset); - - offset += 8; - } - } - break; - case ArgAggregate: - { - for(j=0; jnregs; j++) - { - 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, - (inst->inst_offset + (8*j))); - offset += 8; - } - } - break; - case ArgInDoubleReg: - case ArgInFloatReg: - // We need to save all used af0-af5 params - { - switch(cinfo->args[i].storage) - { - case ArgInFloatReg: - //alpha_sts(code, ainfo->reg, alpha_fp, offset); - alpha_sts(code, ainfo->reg, inst->inst_basereg, inst->inst_offset); - break; - case ArgInDoubleReg: - //alpha_stt(code, ainfo->reg, alpha_fp, offset); - alpha_stt(code, ainfo->reg, inst->inst_basereg, inst->inst_offset); - break; - default: - ; - } - - CFG_DEBUG(3) g_print("ALPHA: Saved float arg reg %d at offset: %0lx\n", - ainfo->reg, /*offset*/inst->inst_offset); - - offset += 8; - } - } - } - - offset = cfg->arch.reg_save_area_offset; - - /* - for (i = 0; i < MONO_MAX_VREGS; ++i) - if (ALPHA_IS_CALLEE_SAVED_REG (i) && - (cfg->used_int_regs & (1 << i)) && - !( ALPHA_ARGS_REGS & (1 << i)) ) - { - alpha_stq(code, i, alpha_fp, offset); - CFG_DEBUG(3) g_print("ALPHA: Saved caller reg %d at offset: %0x\n", - i, offset); - offset += 8; - } - */ - // TODO - check amd64 code for "Might need to attach the thread to the JIT" - - if (method->save_lmf) - { - /* - * The call might clobber argument registers, but they are already - * saved to the stack/global regs. - */ - - code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, - (gpointer)"mono_get_lmf_addr"); - - // Save lmf_addr - alpha_stq(code, alpha_r0, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, lmf_addr))); - // Load "previous_lmf" member of MonoLMF struct - alpha_ldq(code, alpha_r1, alpha_r0, 0); - - // Save it to MonoLMF struct - alpha_stq(code, alpha_r1, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, previous_lmf))); - - // Set new LMF - alpha_lda(code, alpha_r1, alpha_fp, lmf_offset); - alpha_stq(code, alpha_r1, alpha_r0, 0); - } - - g_free (cinfo); - - if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) - code = mono_arch_instrument_prolog (cfg, mono_trace_enter_method, - code, TRUE); - - cfg->code_len = ((char *)code) - ((char *)cfg->native_code); - - g_assert (cfg->code_len < cfg->code_size); - - return (gint8 *)code; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_flush_register_windows */ -/* */ -/* Function - */ -/* */ -/* Returns - */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_flush_register_windows (void) -{ - ALPHA_DEBUG("mono_arch_flush_register_windows"); -} -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_regalloc_cost */ -/* */ -/* Function - Determine the cost, in the number of memory */ -/* references, of the action of allocating the var- */ -/* iable VMV into a register during global register */ -/* allocation. */ -/* */ -/* Returns - Cost */ -/* */ -/*------------------------------------------------------------------*/ - -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"); - - if (cfg->method->save_lmf) - /* The register is already saved */ - /* substract 1 for the invisible store in the prolog */ - return (ins->opcode == OP_ARG) ? 1 : 0; - else - /* push+pop */ - return (ins->opcode == OP_ARG) ? 2 : 1; -} - -/*========================= End of Function ========================*/ - -/* -** -** This method emits call sequience -** -*/ -static unsigned int * -emit_call(MonoCompile *cfg, unsigned int *code, - guint32 patch_type, gconstpointer data) -{ - int offset; - AlphaGotData ge_data; - - offset = (char *)code - (char *)cfg->native_code; - - ge_data.data.p = (void *)data; - add_got_entry(cfg, GT_PTR, ge_data, - offset, patch_type, data); - - // Load call address into PV - alpha_ldq(code, alpha_pv, alpha_gp, 0); - - // Call method - alpha_jsr(code, alpha_ra, alpha_pv, 0); - - offset = (char *)code - (char *)cfg->native_code; - - // Restore GP - ALPHA_LOAD_GP(offset) - alpha_ldah(code, alpha_gp, alpha_ra, 0); - alpha_lda(code, alpha_gp, alpha_gp, 0); - - return code; -} - -/*------------------------------------------------------------------*/ -/* */ -/* Name - arch_get_argument_info */ -/* */ -/* Function - Gathers information on parameters such as size, */ -/* alignment, and padding. arg_info should be large */ -/* enough to hold param_count + 1 entries. */ -/* */ -/* Parameters - @csig - Method signature */ -/* @param_count - No. of parameters to consider */ -/* @arg_info - An array to store the result info */ -/* */ -/* Returns - Size of the activation frame */ -/* */ -/*------------------------------------------------------------------*/ - -int -mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, - int param_count, - MonoJitArgumentInfo *arg_info) -{ - int k; - CallInfo *cinfo = get_call_info (NULL, csig, FALSE); - guint32 args_size = cinfo->stack_usage; - - ALPHA_DEBUG("mono_arch_get_argument_info"); - - /* The arguments are saved to a stack area in mono_arch_instrument_prolog */ - if (csig->hasthis) - { - arg_info [0].offset = 0; - } - - for (k = 0; k < param_count; k++) - { - arg_info [k + 1].offset = ((k + csig->hasthis) * 8); - - /* FIXME: */ - // Set size to 1 - // The size is checked only for valuetype in trace.c - arg_info [k + 1].size = 8; - } - - g_free (cinfo); - - return args_size; -} - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_emit_epilog */ -/* */ -/* Function - Emit the instructions for a function epilog. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_emit_epilog (MonoCompile *cfg) -{ - MonoMethod *method = cfg->method; - int offset, i; - unsigned int *code; - int max_epilog_size = 128; - int stack_size = cfg->arch.stack_size; - // CallInfo *cinfo; - gint32 lmf_offset = cfg->arch.lmf_offset; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_emit_epilog"); - - while (cfg->code_len + max_epilog_size > (cfg->code_size - 16)) - { - cfg->code_size *= 2; - cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); - cfg->stat_code_reallocs++; - } - - code = (unsigned int *)(cfg->native_code + cfg->code_len); - - if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) - code = mono_arch_instrument_epilog (cfg, mono_trace_leave_method, - code, TRUE); - - if (method->save_lmf) - { - /* Restore previous lmf */ - alpha_ldq(code, alpha_at, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf))); - alpha_ldq(code, alpha_ra, alpha_fp, - (lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr))); - alpha_stq(code, alpha_at, alpha_ra, 0); - } - - // 5 instructions. - alpha_mov1( code, alpha_fp, alpha_sp ); - - // Restore saved regs - offset = cfg->arch.reg_save_area_offset; - - for (i = 0; i < MONO_MAX_IREGS; ++i) - if (ALPHA_IS_CALLEE_SAVED_REG (i) && - (cfg->used_int_regs & (1 << i)) && - !( ALPHA_ARGS_REGS & (1 << i)) ) - { - alpha_ldq(code, i, alpha_sp, offset); - CFG_DEBUG(3) g_print("ALPHA: Restored caller reg %d at offset: %0x\n", - i, offset); - offset += 8; - } - - /* restore fp, ra, sp */ - offset = cfg->arch.params_stack_size; - - alpha_ldq( code, alpha_ra, alpha_sp, (offset + 0) ); - alpha_ldq( code, alpha_fp, alpha_sp, (offset + 8) ); - alpha_lda( code, alpha_sp, alpha_sp, stack_size ); - - /* return */ - alpha_ret( code, alpha_ra, 1 ); - - cfg->code_len = ((char *)code) - ((char *)cfg->native_code); - - g_assert (cfg->code_len < cfg->code_size); -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_emit_exceptions */ -/* */ -/* Function - Emit the blocks to handle exception conditions. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_emit_exceptions (MonoCompile *cfg) -{ - MonoJumpInfo *patch_info; - int nthrows, i; - unsigned int *code, *got_start; - unsigned long *corlib_exc_adr; - MonoClass *exc_classes [16]; - guint8 *exc_throw_start [16], *exc_throw_end [16]; - guint32 code_size = 8; // Reserve space for address to mono_arch_throw_corlib_exception - AlphaGotEntry *got_data; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_emit_exceptions"); - - /* Compute needed space */ - for (patch_info = cfg->patch_info; patch_info; - patch_info = patch_info->next) - { - if (patch_info->type == MONO_PATCH_INFO_EXC) - code_size += 40; - if (patch_info->type == MONO_PATCH_INFO_R8) - code_size += 8 + 7; /* sizeof (double) + alignment */ - if (patch_info->type == MONO_PATCH_INFO_R4) - code_size += 4 + 7; /* sizeof (float) + alignment */ - } - - // Reserve space for GOT entries - for (got_data = cfg->arch.got_data; got_data; - got_data = got_data->next) - { - // Reserve space for 8 byte const (for now) - if (got_data->type != GT_LD_GTADDR) - code_size += 8; - } - - while (cfg->code_len + code_size > (cfg->code_size - 16)) - { - cfg->code_size *= 2; - cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); - cfg->stat_code_reallocs++; - } - - code = (unsigned int *)((char *)cfg->native_code + cfg->code_len); - - // Set code alignment - if (((unsigned long)code) % 8) - code++; - - got_start = code; - - /* Add code to store conts and modify patch into to store offset in got */ - for (got_data = cfg->arch.got_data; got_data; - got_data = got_data->next) - { - unsigned long data = got_data->value.data.l; - MonoJumpInfo *got_ref = got_data->got_patch_info; - - // Modify loading of GP - if (got_data->type == GT_LD_GTADDR) - { - short high_off, low_off; - unsigned int *ldgp_code = - (unsigned int *)(cfg->native_code + got_data->value.data.l); - unsigned int got_off = (char *)got_start - (char *)ldgp_code; - - high_off = got_off / 0x10000; - low_off = got_off % 0x10000; - if (low_off < 0) - high_off++; - - // Set offset from current point to GOT array - // modify the following code sequence - // ldah gp, 0(pv) or ldah gp, 0(ra) - // lda gp, 0(gp) - *ldgp_code = (*ldgp_code | (high_off & 0xFFFF)); - ldgp_code++; - *ldgp_code = (*ldgp_code | (low_off & 0xFFFF)); - - continue; - } - - patch_info = got_data->patch_info; - - // Check code alignment - if (((unsigned long)code) % 8) - code++; - - got_ref->data.offset = ((char *)code - (char *)got_start); - - if (patch_info) - patch_info->ip.i = ((char *)code - (char *)cfg->native_code); - - *code = (unsigned int)(data & 0xFFFFFFFF); - code++; - *code = (unsigned int)((data >> 32) & 0xFFFFFFFF); - code++; - - } - - corlib_exc_adr = (unsigned long *)code; - - /* add code to raise exceptions */ - nthrows = 0; - for (patch_info = cfg->patch_info; patch_info; - patch_info = patch_info->next) - { - switch (patch_info->type) - { - case MONO_PATCH_INFO_EXC: - { - MonoClass *exc_class; - unsigned int *buf, *buf2; - guint32 throw_ip; - - if (nthrows == 0) - { - // Add patch info to call mono_arch_throw_corlib_exception - // method to raise corlib exception - // Will be added at the begining of the patch info list - mono_add_patch_info(cfg, - ((char *)code - (char *)cfg->native_code), - MONO_PATCH_INFO_INTERNAL_METHOD, - "mono_arch_throw_corlib_exception"); - - // Skip longword before starting the code - *code++ = 0; - *code++ = 0; - } - - exc_class = mono_class_from_name (mono_defaults.corlib, - "System", patch_info->data.name); - - g_assert (exc_class); - throw_ip = patch_info->ip.i; - - //x86_breakpoint (code); - /* Find a throw sequence for the same exception class */ - for (i = 0; i < nthrows; ++i) - if (exc_classes [i] == exc_class) - break; - - if (i < nthrows) - { - int br_offset; - - // Patch original branch (patch info) to jump here - patch_info->type = MONO_PATCH_INFO_METHOD_REL; - patch_info->data.target = - (char *)code - (char *)cfg->native_code; - - alpha_lda(code, alpha_a1, alpha_zero, - -((short)((((char *)exc_throw_end[i] - - (char *)cfg->native_code)) - throw_ip) - 4) ); - - br_offset = ((char *)exc_throw_start[i] - (char *)code - 4)/4; - - alpha_bsr(code, alpha_zero, br_offset); - } - else - { - buf = code; - - // Save exception token type as first 32bit word for new - // exception handling jump code - *code = exc_class->type_token; - code++; - - // Patch original branch (patch info) to jump here - patch_info->type = MONO_PATCH_INFO_METHOD_REL; - patch_info->data.target = - (char *)code - (char *)cfg->native_code; - - buf2 = code; - alpha_lda(code, alpha_a1, alpha_zero, 0); - - if (nthrows < 16) - { - exc_classes [nthrows] = exc_class; - exc_throw_start [nthrows] = code; - } - - // Load exception token - alpha_ldl(code, alpha_a0, alpha_gp, - ((char *)buf - (char *)got_start /*cfg->native_code*/)); - // Load corlib exception raiser code address - alpha_ldq(code, alpha_pv, alpha_gp, - ((char *)corlib_exc_adr - - (char *)got_start /*cfg->native_code*/)); - - //amd64_mov_reg_imm (code, AMD64_RDI, exc_class->type_token); - //patch_info->data.name = "mono_arch_throw_corlib_exception"; - //**patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD; - //patch_info->type = MONO_PATCH_INFO_NONE; - //patch_info->ip.i = (char *)code - (char *)cfg->native_code; - - if (cfg->compile_aot) - { - // amd64_mov_reg_membase (code, GP_SCRATCH_REG, AMD64_RIP, 0, 8); - //amd64_call_reg (code, GP_SCRATCH_REG); - } else { - /* The callee is in memory allocated using - the code manager */ - alpha_jsr(code, alpha_ra, alpha_pv, 0); - } - - alpha_lda(buf2, alpha_a1, alpha_zero, - -((short)(((char *)code - (char *)cfg->native_code) - - throw_ip)-4) ); - - if (nthrows < 16) - { - exc_throw_end [nthrows] = code; - nthrows ++; - } - } - break; - } - default: - /* do nothing */ - break; - } - } - - /* Handle relocations with RIP relative addressing */ - for (patch_info = cfg->patch_info; patch_info; - patch_info = patch_info->next) - { - gboolean remove = FALSE; - - switch (patch_info->type) - { - case MONO_PATCH_INFO_R8: - { - guint8 *pos; - - code = (guint8*)ALIGN_TO (code, 8); - - pos = cfg->native_code + patch_info->ip.i; - - *(double*)code = *(double*)patch_info->data.target; - - // if (use_sse2) - // *(guint32*)(pos + 4) = (guint8*)code - pos - 8; - //else - *(guint32*)(pos + 3) = (guint8*)code - pos - 7; - code += 8; - - remove = TRUE; - break; - } - case MONO_PATCH_INFO_R4: - { - guint8 *pos; - - code = (guint8*)ALIGN_TO (code, 8); - - pos = cfg->native_code + patch_info->ip.i; - - *(float*)code = *(float*)patch_info->data.target; - - //if (use_sse2) - // *(guint32*)(pos + 4) = (guint8*)code - pos - 8; - //else - *(guint32*)(pos + 3) = (guint8*)code - pos - 7; - code += 4; - - remove = TRUE; - break; - } - default: - break; - } - - if (remove) - { - if (patch_info == cfg->patch_info) - cfg->patch_info = patch_info->next; - else - { - MonoJumpInfo *tmp; - - for (tmp = cfg->patch_info; tmp->next != patch_info; - tmp = tmp->next) - ; - tmp->next = patch_info->next; - } - } - } - - cfg->code_len = (char *)code - (char *)cfg->native_code; - - g_assert (cfg->code_len < cfg->code_size); - -} - -/*========================= End of Function ========================*/ - -#define EMIT_ALPHA_BRANCH(Tins, PRED_REG, ALPHA_BR) \ - offset = ((char *)code - \ - (char *)cfg->native_code); \ - if (Tins->inst_true_bb->native_offset) \ - { \ - long br_offset = (char *)cfg->native_code + \ - Tins->inst_true_bb->native_offset - 4 - (char *)code; \ - CFG_DEBUG(3) g_print("jump to: native_offset: %0X, address %p]\n", \ - Tins->inst_target_bb->native_offset, \ - cfg->native_code + \ - Tins->inst_true_bb->native_offset); \ - alpha_##ALPHA_BR (code, PRED_REG, br_offset/4); \ - } \ - else \ - { \ - CFG_DEBUG(3) g_print("add patch info: MONO_PATCH_INFO_BB offset: %0X, target_bb: %p]\n", \ - offset, Tins->inst_target_bb); \ - mono_add_patch_info (cfg, offset, \ - MONO_PATCH_INFO_BB, \ - Tins->inst_true_bb); \ - alpha_##ALPHA_BR (code, PRED_REG, 0); \ - } - - -#define EMIT_COND_EXC_BRANCH(ALPHA_BR, PRED_REG, EXC_NAME) \ - do \ - { \ - MonoInst *tins = mono_branch_optimize_exception_target (cfg, \ - bb, \ - EXC_NAME); \ - if (tins == NULL) \ - { \ - mono_add_patch_info (cfg, \ - ((char *)code - \ - (char *)cfg->native_code), \ - MONO_PATCH_INFO_EXC, EXC_NAME); \ - alpha_##ALPHA_BR(code, PRED_REG, 0); \ - } \ - else \ - { \ - EMIT_ALPHA_BRANCH(tins, PRED_REG, ALPHA_BR); \ - } \ - } while(0); - - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_output_basic_block */ -/* */ -/* Function - Perform the "real" work of emitting instructions */ -/* that will do the work of in the basic block. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) -{ - MonoInst *ins; - MonoCallInst *call; - guint offset; - unsigned int *code = (unsigned int *)(cfg->native_code + cfg->code_len); - MonoInst *last_ins = NULL; - guint last_offset = 0; - int max_len, cpos; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_output_basic_block"); - - CFG_DEBUG(2) g_print ("Basic block %d(%p) starting at offset 0x%x\n", - bb->block_num, bb, bb->native_offset); - - cpos = bb->max_offset; - - offset = ((char *)code) - ((char *)cfg->native_code); - - mono_debug_open_block (cfg, bb, offset); - - MONO_BB_FOR_EACH_INS (bb, ins) { - offset = ((char *)code) - ((char *)cfg->native_code); - - max_len = ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN]; - - if (offset > (cfg->code_size - max_len - 16)) - { - cfg->code_size *= 2; - cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); - code = (unsigned int *)(cfg->native_code + offset); - cfg->stat_code_reallocs++; - } - - mono_debug_record_line_number (cfg, ins, offset); - - CFG_DEBUG(3) g_print("ALPHA: Emiting [%s] opcode\n", - mono_inst_name(ins->opcode)); - - switch (ins->opcode) - { - case OP_RELAXED_NOP: - break; - case OP_LSHR: - // Shift 64 bit value right - CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_sra(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_LSHR_UN: - // Shift 64 bit value right - CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr_un] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_srl(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_LSHR_IMM: - // Shift 64 bit value right by constant - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr_imm] dreg=%d, sreg1=%d, const=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - alpha_sra_(code, ins->sreg1, ins->inst_imm, ins->dreg); - break; - - case OP_ISHL: - // Shift 32 bit value left - CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shl] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_sll(code, ins->sreg1, ins->sreg2, ins->dreg); - alpha_addl_(code, ins->dreg, 0, ins->dreg); - break; - - case OP_ISHL_IMM: - // Shift 32 bit value left by constant - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shl_imm] dreg=%d, sreg1=%d, const=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - alpha_sll_(code, ins->sreg1, ins->inst_imm, ins->dreg); - alpha_addl_(code, ins->dreg, 0, ins->dreg); - break; - - case OP_SHL_IMM: - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [shl_imm] dreg=%d, sreg1=%d, const=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - alpha_sll_(code, ins->sreg1, ins->inst_imm, ins->dreg); - break; - - case OP_LSHL_IMM: - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shl_imm] dreg=%d, sreg1=%d, const=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - alpha_sll_(code, ins->sreg1, ins->inst_imm, ins->dreg); - break; - - - case CEE_SHL: - // Shift 32 bit value left - CFG_DEBUG(4) g_print("ALPHA_CHECK: [shl] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_sll(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_LSHL: - // Shift 64 bit value left - CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shl] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_sll(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - - case OP_ISHR: - // Shift 32 bit value right - CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shr] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - //alpha_zap_(code, ins->sreg1, 0xF0, ins->dreg); - alpha_sra(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_ISHR_IMM: - // Shift 32 bit value rigth by constant - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_shr_imm] dreg=%d, sreg1=%d, const=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - //alpha_zap_(code, ins->sreg1, 0xF0, ins->dreg); - alpha_sra_(code, ins->sreg1, ins->inst_imm, ins->dreg); - break; - - case OP_ISHR_UN: - // 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, 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, alpha_at /*ins->dreg*/); - alpha_srl_(code, alpha_at /*ins->dreg*/, ins->inst_imm, ins->dreg); - break; - - case OP_LSHR_UN_IMM: - // Shift 64 bit unassigned value rigth by constant - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [long_shr_un_imm] dreg=%d, sreg1=%d, const=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - alpha_srl_(code, ins->sreg1, ins->inst_imm, ins->dreg); - break; - - case CEE_ADD: - // Sum two 64 bits regs - CFG_DEBUG(4) g_print("ALPHA_CHECK: [add] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_addq(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case CEE_SUB: - // Subtract two 64 bit regs - CFG_DEBUG(4) g_print("ALPHA_CHECK: [sub] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_subq(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_ADD_IMM: - // Add imm value to 64 bits int - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [add_imm] dreg=%d, sreg1=%d, imm=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - alpha_addq_(code, ins->sreg1, ins->inst_imm, ins->dreg); - break; - - case OP_IADD: - // Add two 32 bit ints - CFG_DEBUG(4) g_print("ALPHA_CHECK: [iadd] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_addl(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_IADDCC: - // Add two 32 bit ints with overflow detection - // Use AT to hold flag of signed overflow - // Use t12(PV) to hold unsigned overflow - // Use RA to hold intermediate result - CFG_DEBUG(4) g_print("ALPHA_CHECK: [iaddcc] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_addl(code, ins->sreg1, ins->sreg2, alpha_ra); - alpha_ble(code, ins->sreg2, 2); - - /* (sreg2 > 0) && (res < ins->sreg1) => signed overflow */ - alpha_cmplt(code, alpha_ra, ins->sreg1, alpha_at); - alpha_br(code, alpha_zero, 1); - - /* (sreg2 <= 0) && (res > ins->sreg1) => signed overflow */ - alpha_cmplt(code, ins->sreg1, alpha_ra, alpha_at); - - /* res unsigned overflow */ - alpha_cmpult(code, alpha_ra, ins->sreg1, alpha_pv); - - alpha_mov1(code, alpha_ra, ins->dreg); - break; - - case OP_ADDCC: - // Add two 64 bit ints with overflow detection - // Use AT to hold flag of signed overflow - // Use t12(PV) to hold unsigned overflow - // Use RA to hold intermediate result - CFG_DEBUG(4) g_print("ALPHA_CHECK: [addcc] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_addq(code, ins->sreg1, ins->sreg2, alpha_ra); - alpha_ble(code, ins->sreg2, 2); - - /* (sreg2 > 0) && (res < ins->sreg1) => signed overflow */ - alpha_cmplt(code, alpha_ra, ins->sreg1, alpha_at); - alpha_br(code, alpha_zero, 1); - - /* (sreg2 <= 0) && (res > ins->sreg1) => signed overflow */ - alpha_cmplt(code, ins->sreg1, alpha_ra, alpha_at); - - /* res unsigned overflow */ - alpha_cmpult(code, alpha_ra, ins->sreg1, alpha_pv); - - alpha_mov1(code, alpha_ra, ins->dreg); - break; - - case OP_IADD_IMM: - // Add imm value to 32 bits int - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [iadd_imm] dreg=%d, sreg1=%d, imm=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - alpha_addl_(code, ins->sreg1, ins->inst_imm, ins->dreg); - break; - - case OP_ISUB: - // Substract to 32 bit ints - CFG_DEBUG(4) g_print("ALPHA_CHECK: [isub] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_subl(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_ISUB_IMM: - // Sub imm value from 32 bits int - g_assert(alpha_is_imm(ins->inst_imm)); - CFG_DEBUG(4) g_print("ALPHA_CHECK: [isub_imm] dreg=%d, sreg1=%d, imm=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - alpha_subl_(code, ins->sreg1, ins->inst_imm, ins->dreg); - break; - - case OP_ISUBCC: - // Sub to 32 bit ints with overflow detection - CFG_DEBUG(4) g_print("ALPHA_CHECK: [isubcc] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_subl(code, ins->sreg1, ins->sreg2, alpha_ra); - alpha_ble(code, ins->sreg2, 2); - - /* (sreg2 > 0) && (res > ins->sreg1) => signed overflow */ - alpha_cmplt(code, ins->sreg1, alpha_ra, alpha_at); - alpha_br(code, alpha_zero, 1); - - /* (sreg2 <= 0) && (res < ins->sreg1) => signed overflow */ - alpha_cmplt(code, alpha_ra, ins->sreg1, alpha_at); - - /* sreg1 unsigned overflow */ - alpha_cmpult(code, ins->sreg1, ins->sreg2, alpha_pv); - - alpha_mov1(code, alpha_ra, ins->dreg); - break; - - case OP_SUBCC: - // Sub to 64 bit ints with overflow detection - CFG_DEBUG(4) g_print("ALPHA_CHECK: [subcc] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - - alpha_subq(code, ins->sreg1, ins->sreg2, alpha_ra); - alpha_ble(code, ins->sreg2, 2); - - /* (sreg2 > 0) && (res > ins->sreg1) => signed overflow */ - alpha_cmplt(code, ins->sreg1, alpha_ra, alpha_at); - alpha_br(code, alpha_zero, 1); - - /* (sreg2 <= 0) && (res < ins->sreg1) => signed overflow */ - alpha_cmplt(code, alpha_ra, ins->sreg1, alpha_at); - - /* sreg1 unsigned overflow */ - alpha_cmpult(code, ins->sreg1, ins->sreg2, alpha_pv); - - alpha_mov1(code, alpha_ra, ins->dreg); - break; - - case OP_IAND: - case CEE_AND: - // AND to 32 bit ints - CFG_DEBUG(4) g_print("ALPHA_CHECK: [iand/and] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_and(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_IAND_IMM: - case OP_AND_IMM: - // AND imm value with 32 bit int - CFG_DEBUG(4) g_print("ALPHA_CHECK: [iand_imm/and_imm] dreg=%d, sreg1=%d, imm=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - - g_assert(alpha_is_imm(ins->inst_imm)); - alpha_and_(code, ins->sreg1, ins->inst_imm, ins->dreg); - - break; - - case OP_IOR: - case CEE_OR: - // OR two 32/64 bit ints - CFG_DEBUG(4) g_print("ALPHA_CHECK: [ior/or] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_bis(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_IOR_IMM: - // OR imm value with 32 bit int - CFG_DEBUG(4) g_print("ALPHA_CHECK: [ior_imm] dreg=%d, sreg1=%d, imm=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - - g_assert(alpha_is_imm(ins->inst_imm)); - alpha_bis_(code, ins->sreg1, ins->inst_imm, ins->dreg); - - break; - - case OP_IXOR: - case CEE_XOR: - // XOR two 32/64 bit ints - CFG_DEBUG(4) g_print("ALPHA_CHECK: [ixor/xor] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_xor(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_IXOR_IMM: - // XOR imm value with 32 bit int - CFG_DEBUG(4) g_print("ALPHA_CHECK: [ixor_imm] dreg=%d, sreg1=%d, imm=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - - g_assert(alpha_is_imm(ins->inst_imm)); - alpha_xor_(code, ins->sreg1, ins->inst_imm, ins->dreg); - - break; - - case OP_INEG: - // NEG 32 bit reg - CFG_DEBUG(4) g_print("ALPHA_CHECK: [ineg] dreg=%d, sreg1=%d\n", - ins->dreg, ins->sreg1); - alpha_subl(code, alpha_zero, ins->sreg1, ins->dreg); - break; - - case CEE_NEG: - // NEG 64 bit reg - CFG_DEBUG(4) g_print("ALPHA_CHECK: [neg] dreg=%d, sreg1=%d\n", - ins->dreg, ins->sreg1); - alpha_subq(code, alpha_zero, ins->sreg1, ins->dreg); - break; - - case OP_INOT: - case CEE_NOT: - // NOT 32/64 bit reg - CFG_DEBUG(4) g_print("ALPHA_CHECK: [inot/not] dreg=%d, sreg1=%d\n", - ins->dreg, ins->sreg1); - alpha_not(code, ins->sreg1, ins->dreg); - break; - - - case OP_IDIV: - case OP_IREM: - case OP_IMUL: - case OP_IMUL_OVF: - case OP_IMUL_OVF_UN: - case OP_IDIV_UN: - case OP_IREM_UN: - CFG_DEBUG(4) g_print("ALPHA_TODO: [idiv/irem/imul/imul_ovf/imul_ovf_un/idiv_un/irem_un] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - break; - - case CEE_MUL: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [mul] dreg=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_mull(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_IMUL_IMM: - CFG_DEBUG(4) g_print("ALPHA_TODO: [imul_imm] dreg=%d, sreg1=%d, imm=%ld\n", - ins->dreg, ins->sreg1, ins->inst_imm); - break; - - case OP_CHECK_THIS: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [check_this] sreg1=%d\n", - ins->sreg1); - alpha_ldl(code, alpha_at, ins->sreg1, 0); - break; - - case OP_SEXT_I1: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [sext_i1] dreg=%d, sreg1=%d\n", - ins->dreg, ins->sreg1); - alpha_sll_(code, ins->sreg1, 56, ins->dreg); - alpha_sra_(code, ins->dreg, 56, ins->dreg); - break; - - case OP_SEXT_I2: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [sext_i2] dreg=%d, sreg1=%d\n", - ins->dreg, ins->sreg1); - alpha_sll_(code, ins->sreg1, 48, ins->dreg); - alpha_sra_(code, ins->dreg, 48, ins->dreg); - break; - - case OP_SEXT_I4: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [sext_i4] dreg=%d, sreg1=%d\n", - ins->dreg, ins->sreg1); - alpha_sll_(code, ins->sreg1, 32, ins->dreg); - alpha_sra_(code, ins->dreg, 32, ins->dreg); - break; - - case OP_ICONST: - // Actually ICONST is 32 bits long - CFG_DEBUG(4) g_print("ALPHA_CHECK: [iconst] dreg=%d, const=%0lX\n", - ins->dreg, ins->inst_c0); - - // if const = 0 - if (ins->inst_c0 == 0) - { - alpha_clr(code, ins->dreg); - break; - } - - // if -32768 < const <= 32767 - if (ins->inst_c0 > -32768 && ins->inst_c0 <= 32767) - { - alpha_lda( code, ins->dreg, alpha_zero, ins->inst_c0); - //if (ins->inst_c0 & 0xFFFFFFFF00000000L) - // alpha_zap_(code, ins->dreg, 0xF0, ins->dreg); - } - else - { - int lo = (char *)code - (char *)cfg->native_code; - AlphaGotData ge_data; - - //ge_data.data.l = (ins->inst_c0 & 0xFFFFFFFF); - ge_data.data.l = ins->inst_c0; - - add_got_entry(cfg, GT_LONG, ge_data, - lo, MONO_PATCH_INFO_NONE, 0); - //mono_add_patch_info(cfg, lo, MONO_PATCH_INFO_GOT_OFFSET, - // ins->inst_c0); - //alpha_ldl(code, ins->dreg, alpha_gp, 0); - alpha_ldq(code, ins->dreg, alpha_gp, 0); - } - - break; - case OP_I8CONST: - { - int lo; - - // To load 64 bit values we will have to use ldah/lda combination - // and temporary register. As temporary register use r28 - // Divide 64 bit value in two parts and load upper 32 bits into - // temp reg, lower 32 bits into dreg. Later set higher 32 bits in - // dreg from temp reg - // the 32 bit value could be loaded with ldah/lda - CFG_DEBUG(4) g_print("ALPHA_CHECK: [i8conts] dreg=%d, const=%0lX\n", - ins->dreg, ins->inst_c0); - - // if const = 0 - if (ins->inst_c0 == 0) - { - alpha_clr(code, ins->dreg); - break; - } - - // if -32768 < const <= 32767 - if (ins->inst_c0 > -32768 && ins->inst_c0 <= 32767) - alpha_lda( code, ins->dreg, alpha_zero, ins->inst_c0); - else - { - AlphaGotData ge_data; - - lo = (char *)code - (char *)cfg->native_code; - - ge_data.data.l = ins->inst_c0; - - add_got_entry(cfg, GT_LONG, ge_data, - lo, MONO_PATCH_INFO_NONE, 0); - alpha_ldq(code, ins->dreg, alpha_gp, 0); - } - break; - } - - case OP_R8CONST: - { - double d = *(double *)ins->inst_p0; - AlphaGotData ge_data; - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [r8const] dreg=%d, r8const=%g\n", - ins->dreg, d); - - ge_data.data.d = d; - add_got_entry(cfg, GT_DOUBLE, ge_data, - (char *)code - (char *)cfg->native_code, - MONO_PATCH_INFO_NONE, 0); - alpha_ldt(code, ins->dreg, alpha_gp, 0); - - break; - } - - case OP_R4CONST: - { - float d = *(float *)ins->inst_p0; - AlphaGotData ge_data; - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [r4const] dreg=%d, r4const=%f\n", - ins->dreg, d); - - ge_data.data.f = d; - add_got_entry(cfg, GT_FLOAT, ge_data, - (char *)code - (char *)cfg->native_code, - MONO_PATCH_INFO_NONE, 0); - alpha_lds(code, ins->dreg, alpha_gp, 0); - - break; - } - - case OP_LOADU4_MEMBASE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadu4_membase] dreg=%d, basereg=%d, offset=%0lx\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - - alpha_ldl(code, ins->dreg, ins->inst_basereg, ins->inst_offset); - // alpha_zapnot_(code, ins->dreg, 0x0F, ins->dreg); - break; - - case OP_LOADU1_MEMBASE: - // Load unassigned byte from REGOFFSET - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadu1_membase] dreg=%d, basereg=%d, offset=%0lx\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - if (bwx_supported) - alpha_ldbu(code, ins->dreg, ins->inst_basereg, ins->inst_offset); - else - { - alpha_ldq_u(code, alpha_r25, ins->inst_basereg, - ins->inst_offset); - alpha_lda(code, alpha_at, ins->inst_basereg, ins->inst_offset); - alpha_extbl(code, alpha_r25, alpha_at, ins->dreg); - } - break; - - case OP_LOADU2_MEMBASE: - // Load unassigned word from REGOFFSET - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadu2_membase] dreg=%d, basereg=%d, offset=%0lx\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - - if (bwx_supported) - alpha_ldwu(code, ins->dreg, ins->inst_basereg, ins->inst_offset); - else - { - alpha_ldq_u(code, alpha_r24, ins->inst_basereg, - ins->inst_offset); - alpha_ldq_u(code, alpha_r25, ins->inst_basereg, - (ins->inst_offset+1)); - alpha_lda(code, alpha_at, ins->inst_basereg, ins->inst_offset); - alpha_extwl(code, alpha_r24, alpha_at, ins->dreg); - alpha_extwh(code, alpha_r25, alpha_at, alpha_r25); - alpha_bis(code, alpha_r25, ins->dreg, ins->dreg); - } - break; - - case OP_LOAD_MEMBASE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [load_membase] dreg=%d, basereg=%d, offset=%0lx\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - alpha_ldq( code, ins->dreg, ins->inst_basereg, ins->inst_offset); - break; - - case OP_LOADI8_MEMBASE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadi8_membase] dreg=%d, basereg=%d, offset=%0lx\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - alpha_ldq( code, ins->dreg, ins->inst_basereg, ins->inst_offset); - break; - - case OP_LOADI4_MEMBASE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadi4_membase] dreg=%d, basereg=%d, offset=%0lx\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - alpha_ldl( code, ins->dreg, ins->inst_basereg, ins->inst_offset); - break; - - case OP_LOADI1_MEMBASE: - // Load sign-extended byte from REGOFFSET - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadi1_membase] dreg=%d, basereg=%d, offset=%0lx\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - if (bwx_supported) - { - alpha_ldbu(code, ins->dreg, ins->inst_basereg, - ins->inst_offset); - alpha_sextb(code, ins->dreg, ins->dreg); - } - else - { - alpha_ldq_u(code, alpha_r25, ins->inst_basereg, - ins->inst_offset); - alpha_lda(code, alpha_at, ins->inst_basereg, - (ins->inst_offset+1)); - alpha_extqh(code, alpha_r25, alpha_at, ins->dreg); - alpha_sra_(code, ins->dreg, 56, ins->dreg); - } - break; - - case OP_LOADI2_MEMBASE: - // Load sign-extended word from REGOFFSET - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadi2_membase] dreg=%d, basereg=%d, offset=%0lx\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - if (bwx_supported) - { - alpha_ldwu(code, ins->dreg, ins->inst_basereg, - ins->inst_offset); - alpha_sextw(code, ins->dreg, ins->dreg); - } - else - { - alpha_ldq_u(code, alpha_r24, ins->inst_basereg, - ins->inst_offset); - alpha_ldq_u(code, alpha_r25, ins->inst_basereg, - (ins->inst_offset+1)); - alpha_lda(code, alpha_at, ins->inst_basereg, - (ins->inst_offset+2)); - alpha_extql(code, alpha_r24, alpha_at, ins->dreg); - alpha_extqh(code, alpha_r25, alpha_at, alpha_r25); - alpha_bis(code, alpha_r25, ins->dreg, ins->dreg); - alpha_sra_(code, ins->dreg, 48, ins->dreg); - } - break; - - case OP_STOREI1_MEMBASE_IMM: - // Store signed byte at REGOFFSET - // Valid only for storing 0 - // storei1_membase_reg will do the rest - - 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); - - if (bwx_supported) - alpha_stb(code, alpha_zero, ins->inst_destbasereg, - ins->inst_offset); - else - g_assert_not_reached(); - - break; - - case OP_STOREI1_MEMBASE_REG: - // Store byte at REGOFFSET - CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei1_membase_reg] sreg1=%d, destbasereg=%d, offset=%0lx\n", - ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - if (bwx_supported) - { - alpha_stb(code, ins->sreg1, ins->inst_destbasereg, - ins->inst_offset); - } - else - { - alpha_lda(code, alpha_at, ins->inst_destbasereg, - ins->inst_offset); - alpha_ldq_u(code, alpha_r25, ins->inst_destbasereg, - ins->inst_offset); - alpha_insbl(code, ins->sreg1, alpha_at, alpha_r24); - alpha_mskbl(code, alpha_r25, alpha_at, alpha_r25); - alpha_bis(code, alpha_r25, alpha_r24, alpha_r25); - alpha_stq_u(code, alpha_r25, ins->inst_destbasereg, - ins->inst_offset); - } - break; - - case OP_STOREI2_MEMBASE_IMM: - // Store signed word at REGOFFSET - // Now work only for storing 0 - // For now storei2_membase_reg will do the work - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei2_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); - - if (bwx_supported) - alpha_stw(code, alpha_zero, ins->inst_destbasereg, - ins->inst_offset); - else - g_assert_not_reached(); - - break; - - case OP_STOREI2_MEMBASE_REG: - // Store signed word from reg to REGOFFSET - CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei2_membase_reg] sreg1=%d, destbasereg=%d, offset=%0lx\n", - ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - - if (bwx_supported) - { - alpha_stw(code, ins->sreg1, ins->inst_destbasereg, - ins->inst_offset); - } - else - { - alpha_lda(code, alpha_at, ins->inst_destbasereg, - ins->inst_offset); - alpha_ldq_u(code, alpha_r25, ins->inst_destbasereg, - (ins->inst_offset+1)); - alpha_ldq_u(code, alpha_r24, ins->inst_destbasereg, - ins->inst_offset); - alpha_inswh(code, ins->sreg1, alpha_at, alpha_r23); - alpha_inswl(code, ins->sreg1, alpha_at, alpha_r22); - alpha_mskwh(code, alpha_r25, alpha_at, alpha_r25); - alpha_mskwl(code, alpha_r24, alpha_at, alpha_r24); - alpha_bis(code, alpha_r25, alpha_r23, alpha_r25); - alpha_bis(code, alpha_r24, alpha_r22, alpha_r24); - alpha_stq_u(code, alpha_r25, ins->inst_destbasereg, - (ins->inst_offset+1)); - alpha_stq_u(code, alpha_r24, ins->inst_destbasereg, - ins->inst_offset); - } - - break; - - case OP_STOREI4_MEMBASE_IMM: - // We will get here only with ins->inst_imm = 0 - CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei4_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); - - alpha_stl(code, alpha_zero, - ins->inst_destbasereg, ins->inst_offset); - break; - - case OP_STORER4_MEMBASE_REG: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [storer4_membase_reg] sreg1=%d, destbasereg=%d, offset=%0lX\n", - ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - alpha_sts(code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - break; - - case OP_STORER8_MEMBASE_REG: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [storer8_membase_reg] sreg1=%d, destbasereg=%d, offset=%0lX\n", - ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - alpha_stt(code, ins->sreg1, ins->inst_destbasereg, - ins->inst_offset); - break; - - case OP_LOADR4_MEMBASE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadr4_membase] dreg=%d basereg=%d offset=%0lX\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - alpha_lds(code, ins->dreg, ins->inst_basereg, ins->inst_offset); - break; - - case OP_LOADR8_MEMBASE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [loadr8_membase] dreg=%d basereg=%d offset=%0lX\n", - ins->dreg, ins->inst_basereg, ins->inst_offset); - alpha_ldt(code, ins->dreg, ins->inst_basereg, ins->inst_offset); - break; - - case OP_FMOVE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fmove] sreg1=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_cpys(code, ins->sreg1, ins->sreg1, ins->dreg); - break; - - case OP_FADD: - // Later check different rounding and exc modes - CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_add] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_addt_su(code, ins->sreg1, ins->sreg2, ins->dreg); - alpha_trapb(code); - break; - - case OP_FSUB: - // Later check different rounding and exc modes - CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_sub] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_subt_su(code, ins->sreg1, ins->sreg2, ins->dreg); - alpha_trapb(code); - break; - - case OP_FMUL: - // Later check different rounding and exc modes - CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_sub] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_mult(code, ins->sreg1, ins->sreg2, ins->dreg); - break; - - case OP_FNEG: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_neg] sreg1=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_cpysn(code, ins->sreg1, ins->sreg1, ins->dreg); - break; - - case OP_ALPHA_TRAPB: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_trapb]\n"); - alpha_trapb(code); - break; - - case OP_ABS: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [float_abs] sreg1=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_cpys(code, alpha_f31, ins->sreg1, ins->dreg); - break; - - case OP_STORE_MEMBASE_IMM: - case OP_STOREI8_MEMBASE_IMM: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [store_membase_imm/storei8_membase_imm] const=%0lx, destbasereg=%d, offset=%0lx\n", - ins->inst_imm, ins->inst_destbasereg, ins->inst_offset); - g_assert(ins->inst_imm == 0); - - alpha_stq(code, alpha_zero, - ins->inst_destbasereg, ins->inst_offset); - - break; - case OP_STORE_MEMBASE_REG: - case OP_STOREI8_MEMBASE_REG: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [store_membase_reg/storei8_membase_reg] sreg1=%d, destbasereg=%d, offset=%0lx\n", - ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - alpha_stq( code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - break; - - case OP_STOREI4_MEMBASE_REG: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [storei4_membase_reg] sreg1=%d, destbasereg=%d, offset=%0lx\n", - ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - alpha_stl( code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset); - break; - - case OP_ICOMPARE_IMM: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [icompare_imm] sreg1=%d, dreg=%d, const=%0lX\n", - ins->sreg1, ins->dreg, ins->inst_imm); - - g_assert_not_reached(); - - break; - - case OP_COMPARE_IMM: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [compare_imm] sreg1=%d, dreg=%d, const=%0lX\n", - ins->sreg1, ins->dreg, ins->inst_imm); - - g_assert_not_reached(); - - break; - - case OP_COMPARE: // compare two 32 bit regs - case OP_LCOMPARE: // compare two 64 bit regs - case OP_FCOMPARE: // compare two floats - CFG_DEBUG(4) g_print("ALPHA_FIX: [compare/lcompare/fcompare] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - - g_assert_not_reached(); - - break; - - case OP_ALPHA_CMPT_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmpt_un] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmptun(code, ins->sreg1, ins->sreg2, (alpha_at+1)); - break; - - case OP_ALPHA_CMPT_UN_SU: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmpt_un_su] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmptun_su(code, ins->sreg1, ins->sreg2, (alpha_at+1)); - break; - - case OP_ALPHA_CMPT_EQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmpt_eq] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmpteq(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMPT_EQ_SU: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmpt_eq_su] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmpteq_su(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - - case OP_ALPHA_CMPT_LT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmpt_lt] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmptlt(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMPT_LT_SU: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmpt_lt_su] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmptlt_su(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMPT_LE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmpt_le] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmptle(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMPT_LE_SU: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmpt_le_su] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmptle_su(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMP_EQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_eq] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmpeq(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMP_IMM_EQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_eq] sreg1=%d, const=%0lX, dreg=%d\n", - ins->sreg1, ins->inst_imm, ins->dreg); - alpha_cmpeq_(code, ins->sreg1, ins->inst_imm, alpha_at); - break; - - case OP_ALPHA_CMP_IMM_ULE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_ule] sreg1=%d, const=%0lX, dreg=%d\n", - ins->sreg1, ins->inst_imm, ins->dreg); - alpha_cmpule_(code, ins->sreg1, ins->inst_imm, alpha_at); - break; - - case OP_ALPHA_CMP_ULT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_ult] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmpult(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMP_IMM_ULT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_ult] sreg1=%d, const=%0lX, dreg=%d\n", - ins->sreg1, ins->inst_imm, ins->dreg); - alpha_cmpult_(code, ins->sreg1, ins->inst_imm, alpha_at); - break; - - case OP_ALPHA_CMP_LE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_le] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmple(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMP_ULE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_ule] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmpule(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - - case OP_ALPHA_CMP_IMM_LE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_le] sreg1=%d, const=%0lX, dreg=%d\n", - ins->sreg1, ins->inst_imm, ins->dreg); - alpha_cmple_(code, ins->sreg1, ins->inst_imm, alpha_at); - break; - - case OP_ALPHA_CMP_LT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_lt] sreg1=%d, sreg2=%d, dreg=%d\n", - ins->sreg1, ins->sreg2, ins->dreg); - alpha_cmplt(code, ins->sreg1, ins->sreg2, alpha_at); - break; - - case OP_ALPHA_CMP_IMM_LT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [alpha_cmp_imm_lt] sreg1=%d, const=%0lX, dreg=%d\n", - ins->sreg1, ins->inst_imm, ins->dreg); - alpha_cmplt_(code, ins->sreg1, ins->inst_imm, alpha_at); - break; - - case OP_COND_EXC_GT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [op_cond_exc_gt] (cmple + beq) Exc: %s\n", - (char *)ins->inst_p1); - - EMIT_COND_EXC_BRANCH(beq, alpha_at, ins->inst_p1); - break; - - case OP_COND_EXC_GT_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [op_cond_exc_gt_un] (cmpule + beq) Exc: %s\n", - (char *)ins->inst_p1); - - EMIT_COND_EXC_BRANCH(beq, alpha_at, ins->inst_p1); - break; - - case OP_COND_EXC_LT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [op_cond_exc_lt] (cmplt + bne) Exc: %s\n", - (char *)ins->inst_p1); - - EMIT_COND_EXC_BRANCH(bne, alpha_at, ins->inst_p1); - break; - - case OP_COND_EXC_LT_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [op_cond_exc_lt_un] (cmpult + bne) Exc: %s\n", - (char *)ins->inst_p1); - - EMIT_COND_EXC_BRANCH(bne, alpha_at, ins->inst_p1); - break; - - - case OP_COND_EXC_LE_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [op_cond_exc_le_un] (cmpule + bne) Exc: %s\n", - (char *)ins->inst_p1); - EMIT_COND_EXC_BRANCH(bne, alpha_at, ins->inst_p1); - break; - - case OP_COND_EXC_NE_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [op_cond_exc_ne_un] (cmpeq + beq) Exc: %s\n", - (char *)ins->inst_p1); - EMIT_COND_EXC_BRANCH(beq, alpha_at, ins->inst_p1); - break; - - case OP_COND_EXC_EQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [op_cond_exc_eq] (cmpeq + bne) Exc: %s\n", - (char *)ins->inst_p1); - EMIT_COND_EXC_BRANCH(bne, alpha_at, ins->inst_p1); - break; - - case OP_COND_EXC_IOV: - case OP_COND_EXC_OV: - EMIT_COND_EXC_BRANCH(bne, alpha_at, "OverflowException"); - break; - - case OP_COND_EXC_IC: - case OP_COND_EXC_C: - EMIT_COND_EXC_BRANCH(bne, alpha_pv, "OverflowException"); - break; - - case CEE_CONV_OVF_U4: - // Convert unsigned 32 bit value to 64 bit reg - // Check overflow - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_ovf_u4] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_cmplt_(code, ins->sreg1, 0, alpha_at); - EMIT_COND_EXC_BRANCH(bne, alpha_at, "OverflowException"); - alpha_mov1(code, ins->sreg1, ins->dreg); - break; - - case CEE_CONV_OVF_I4_UN: - // Convert unsigned 32 bit value to 64 bit reg - // Check overflow - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_ovf_i4_un] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_zap_(code, ins->sreg1, 0x0F, alpha_at); - - EMIT_COND_EXC_BRANCH(bne, alpha_at, "OverflowException"); - alpha_mov1(code, ins->sreg1, ins->dreg); - break; - - case CEE_CONV_I1: - // Move I1 (byte) to dreg(64 bits) and sign extend it - // Read about sextb - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_i1] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - if (bwx_supported) - alpha_sextb(code, ins->sreg1, ins->dreg); - else - { - alpha_sll_(code, ins->sreg1, 24, alpha_at); - alpha_addl(code, alpha_at, alpha_zero, ins->dreg); - alpha_sra_(code, ins->dreg, 24, ins->dreg); - } - break; - - case CEE_CONV_I2: - // Move I2 (word) to dreg(64 bits) and sign extend it - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_i2] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - if (bwx_supported) - alpha_sextw(code, ins->sreg1, ins->dreg); - else - { - alpha_sll_(code, ins->sreg1, 16, alpha_at); - alpha_addl(code, alpha_at, alpha_zero, ins->dreg); - alpha_sra_(code, ins->dreg, 16, ins->dreg); - } - break; - - case CEE_CONV_I4: - // Move I4 (long) to dreg(64 bits) and sign extend it - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_i4] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_addl(code, ins->sreg1, alpha_zero, ins->dreg); - break; - - case CEE_CONV_I8: - case CEE_CONV_I: - // Convert I/I8 (64 bit) to dreg (64 bit) and sign extend it - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_i8/conv_i] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - //alpha_addl(code, ins->sreg1, alpha_zero, ins->dreg); - alpha_mov1(code, ins->sreg1, ins->dreg); - break; - - case CEE_CONV_U1: - // Move U1 (byte) to dreg(64 bits) don't sign extend it - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_u1] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_extbl_(code, ins->sreg1, 0, ins->dreg); - break; - - case CEE_CONV_U2: - // Move U2 (word) to dreg(64 bits) don't sign extend it - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_u2] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_extwl_(code, ins->sreg1, 0, ins->dreg); - break; - - case CEE_CONV_U4: - // Move U4 (long) to dreg(64 bits) don't sign extend it - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_u4] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_extll_(code, ins->sreg1, 0, ins->dreg); - break; - - case CEE_CONV_U8: - case CEE_CONV_U: - // Move U4 (long) to dreg(64 bits) don't sign extend it - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_u8/conv_u] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_extll_(code, ins->sreg1, 0, ins->dreg); - break; - - case OP_FCONV_TO_I4: - case OP_FCONV_TO_I8: - // Move float to 32 bit reg - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fconv_to_i4/fconv_to_i8] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - //alpha_ftoit(code, ins->sreg1, ins->dreg); - 21264/EV6 - alpha_cvttq_c(code, ins->sreg1, ins->sreg1); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stt(code, ins->sreg1, alpha_sp, 0); - alpha_ldq(code, ins->dreg, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - break; - - case OP_FCONV_TO_I2: - // Move float to 16 bit reg - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fconv_to_i2] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - //alpha_ftoit(code, ins->sreg1, ins->dreg); - 21264/EV6 - alpha_cvttq_c(code, ins->sreg1, ins->sreg1); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stt(code, ins->sreg1, alpha_sp, 0); - alpha_ldq(code, ins->dreg, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - alpha_sll_(code, ins->dreg, 48, ins->dreg); - alpha_sra_(code, ins->dreg, 48, ins->dreg); - break; - - case OP_FCONV_TO_U2: - // Move float to 16 bit reg as unsigned - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fconv_to_u2] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - //alpha_ftoit(code, ins->sreg1, ins->dreg); - 21264/EV6 - alpha_cvttq_c(code, ins->sreg1, ins->sreg1); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stt(code, ins->sreg1, alpha_sp, 0); - alpha_ldq(code, ins->dreg, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - alpha_zapnot_(code, ins->dreg, 3, ins->dreg); - break; - - case OP_FCONV_TO_U1: - // Move float to 8 bit reg as unsigned - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fconv_to_u1] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - //alpha_ftoit(code, ins->sreg1, ins->dreg); - 21264/EV6 - alpha_cvttq_c(code, ins->sreg1, ins->sreg1); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stt(code, ins->sreg1, alpha_sp, 0); - alpha_ldq(code, ins->dreg, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - alpha_and_(code, ins->dreg, 0xff, ins->dreg); - break; - - case OP_FCONV_TO_I1: - // Move float to 8 bit reg - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fconv_to_i1] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - //alpha_ftoit(code, ins->sreg1, ins->dreg); - 21264/EV6 - alpha_cvttq_c(code, ins->sreg1, ins->sreg1); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stt(code, ins->sreg1, alpha_sp, 0); - alpha_ldq(code, ins->dreg, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - alpha_sll_(code, ins->dreg, 56, ins->dreg); - alpha_sra_(code, ins->dreg, 56, ins->dreg); - break; - - case CEE_CONV_R4: - case OP_LCONV_TO_R4: - // Move 32/64 bit int into float - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_r4/lconv_r4] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stq(code, ins->sreg1, alpha_sp, 0); - alpha_ldt(code, ins->dreg, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - alpha_cvtqs(code, ins->dreg, ins->dreg); - alpha_trapb(code); - break; - - case CEE_CONV_R8: - case OP_LCONV_TO_R8: - // Move 32/64 bit int into double - CFG_DEBUG(4) g_print("ALPHA_CHECK: [conv_r8/lconv_r8] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stq(code, ins->sreg1, alpha_sp, 0); - alpha_ldt(code, ins->dreg, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - alpha_cvtqt(code, ins->dreg, ins->dreg); - alpha_trapb(code); - break; - - case OP_FCONV_TO_R4: - // Convert 64 bit float to 32 bit float (T -> S) - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fconv_r4] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_cvtts_su(code, ins->sreg1, ins->dreg); - alpha_trapb(code); - break; - - case OP_LOCALLOC: - // Allocate sreg1 bytes on stack, round bytes by 8, - // modify SP, set dreg to end of current stack frame - // top of stack is used for call params - CFG_DEBUG(4) g_print("ALPHA_CHECK: [localloc] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - - alpha_addq_(code, ins->sreg1, (MONO_ARCH_LOCALLOC_ALIGNMENT - 1), ins->sreg1); - alpha_bic_(code, ins->sreg1, (MONO_ARCH_LOCALLOC_ALIGNMENT - 1), ins->sreg1); - if (ins->flags & MONO_INST_INIT) - alpha_mov1(code, ins->sreg1, ins->sreg2); - - alpha_subq(code, alpha_sp, ins->sreg1, alpha_sp); - if (cfg->arch.params_stack_size > 0) - { - alpha_lda(code, ins->dreg, alpha_zero, - (cfg->arch.params_stack_size)); - alpha_addq(code, alpha_sp, ins->dreg, ins->dreg); - } - else - alpha_mov1(code, alpha_sp, ins->dreg); - - if (ins->flags & MONO_INST_INIT) - { - // TODO: Optimize it later - alpha_lda(code, ins->sreg2, ins->sreg2, - -(MONO_ARCH_LOCALLOC_ALIGNMENT)); - alpha_blt(code, ins->sreg2, 3); - alpha_addq(code, ins->sreg2, ins->dreg, alpha_at); - alpha_stq(code, alpha_zero, alpha_at, 0); - alpha_br(code, alpha_zero, -5); - } - - break; - - case OP_MOVE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [move] sreg=%d, dreg=%d\n", - ins->sreg1, ins->dreg); - alpha_mov1(code, ins->sreg1, ins->dreg); - break; - - case OP_CGT_UN: - case OP_ICGT_UN: - case OP_ICGT: - case OP_CGT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [cgt/cgt_un/icgt_un/int_cgt] dreg=%d\n", - ins->dreg); - alpha_clr(code, ins->dreg); - alpha_cmoveq_(code, alpha_at, 1, ins->dreg); - break; - - case OP_ICLT: - case OP_ICLT_UN: - case OP_CLT: - case OP_CLT_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [int_clt/int_clt_un/clt/clt_un] dreg=%d\n", - ins->dreg); - alpha_clr(code, ins->dreg); - alpha_cmovne_(code, alpha_at, 1, ins->dreg); - break; - - case OP_ICEQ: - case OP_CEQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [iceq/ceq] dreg=%d\n", - ins->dreg); - alpha_clr(code, ins->dreg); - alpha_cmovne_(code, alpha_at, 1, ins->dreg); - break; - - case OP_FCEQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fceq] dreg=%d\n", - ins->dreg); - alpha_clr(code, ins->dreg); - alpha_fbeq(code, alpha_at, 1); - alpha_lda(code, ins->dreg, alpha_zero, 1); - - /* - alpha_cvttq_c(code, alpha_at, alpha_at); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stt(code, alpha_at, alpha_sp, 0); - alpha_ldq(code, alpha_at, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - - alpha_cmovne_(code, alpha_at, 1, ins->dreg); - */ - break; - - case OP_FCGT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fcgt] dreg=%d\n", - ins->dreg); - alpha_clr(code, ins->dreg); - alpha_fbne(code, alpha_at, 1); - alpha_lda(code, ins->dreg, alpha_zero, 1); - - /* - alpha_cvttq_c(code, alpha_at, alpha_at); - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stt(code, alpha_at, alpha_sp, 0); - alpha_ldq(code, alpha_at, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - - alpha_cmoveq_(code, alpha_at, 1, ins->dreg); - */ - break; - - - case OP_FCLT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fclt] dreg=%d\n", - ins->dreg); - alpha_clr(code, ins->dreg); - alpha_fbeq(code, alpha_at, 1); - alpha_lda(code, ins->dreg, alpha_zero, 1); - break; - - case OP_FCLT_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fclt_un] dreg=%d\n", - ins->dreg); - - alpha_clr(code, ins->dreg); - alpha_fbne(code, (alpha_at+1), 1); - alpha_fbeq(code, alpha_at, 1); - alpha_lda(code, ins->dreg, alpha_zero, 1); - break; - - - case OP_IBNE_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [ibne_un] ["); - EMIT_ALPHA_BRANCH(ins, alpha_at, bne); - break; - - case OP_FBNE_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbne_un] ["); - alpha_fbeq(code, (alpha_at+1), 1); - alpha_cpys(code, alpha_zero, alpha_zero, alpha_at); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq); - break; - - case OP_FBGE_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbge_un] ["); - alpha_fbeq(code, (alpha_at+1), 1); - alpha_cpys(code, alpha_zero, alpha_zero, alpha_at); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq); - break; - - case OP_FBGE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbge] ["); - alpha_fbne(code, (alpha_at+1), 1); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq); - break; - - case OP_FBLE_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fble_un] ["); - alpha_fbeq(code, (alpha_at+1), 1); - alpha_cpys(code, (alpha_at+1), (alpha_at+1), alpha_at); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbne); - break; - - case OP_FBLE: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fble] ["); - alpha_fbne(code, (alpha_at+1), 1); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbne); - break; - - case OP_FBLT_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fblt_un] ["); - alpha_fbeq(code, (alpha_at+1), 1); - alpha_cpys(code, (alpha_at+1), (alpha_at+1), alpha_at); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbne); - break; - - case OP_FBLT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fblt] ["); - alpha_fbne(code, (alpha_at+1), 1); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbne); - break; - - case OP_FBGT_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbgt_un] ["); - alpha_fbeq(code, (alpha_at+1), 1); - alpha_cpys(code, alpha_zero, alpha_zero, alpha_at); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq); - break; - - case OP_FBGT: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbgt] ["); - alpha_fbne(code, (alpha_at+1), 1); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbeq); - break; - - case OP_IBEQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [ibeq] ["); - EMIT_ALPHA_BRANCH(ins, alpha_at, beq); - break; - - case OP_FBEQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fbeq] ["); - EMIT_ALPHA_BRANCH(ins, alpha_at, fbne); - break; - - case CEE_BEQ: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [beq] ["); - EMIT_ALPHA_BRANCH(ins, alpha_at, beq); - break; - - case CEE_BNE_UN: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [bne_un] ["); - EMIT_ALPHA_BRANCH(ins, alpha_at, bne); - break; - - case OP_LABEL: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [label]\n"); - ins->inst_c0 = (char *)code - (char *)cfg->native_code; - break; - - case OP_BR: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [br] target: %p, next: %p, curr: %p, last: %p [", - ins->inst_target_bb, bb->next_bb, ins, bb->last_ins); - - if (ins->inst_target_bb->native_offset) - { - // Somehow native offset is offset from - // start of the code. So convert it to - // offset branch - long br_offset = (char *)cfg->native_code + - ins->inst_target_bb->native_offset - 4 - (char *)code; - - CFG_DEBUG(4) g_print("jump to: native_offset: %0X, address %p]\n", - ins->inst_target_bb->native_offset, - cfg->native_code + - ins->inst_target_bb->native_offset); - alpha_br(code, alpha_zero, br_offset/4); - } - else - { - CFG_DEBUG(4) g_print("add patch info: MONO_PATCH_INFO_BB offset: %0X, target_bb: %p]\n", - offset, ins->inst_target_bb); - - mono_add_patch_info (cfg, offset, - MONO_PATCH_INFO_BB, - ins->inst_target_bb); - alpha_br(code, alpha_zero, 0); - } - - break; - - case OP_BR_REG: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [br_reg] sreg1=%d\n", - ins->sreg1); - - alpha_jmp(code, alpha_zero, ins->sreg1, 0); - break; - - case OP_FCALL: - case OP_LCALL: - case OP_VCALL: - case OP_VOIDCALL: - case OP_CALL: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fcall/lcall/vcall/voidcall/call] Target: ["); - call = (MonoCallInst*)ins; - - if (ins->flags & MONO_INST_HAS_METHOD) - { - CFG_DEBUG(4) g_print("MONO_PATCH_INFO_METHOD] %p\n", call->method); - code = emit_call (cfg, code, - MONO_PATCH_INFO_METHOD, call->method); - } - else - { - CFG_DEBUG(4) g_print("MONO_PATCH_INFO_ABS] %p\n", call->fptr); - code = emit_call (cfg, code, - MONO_PATCH_INFO_ABS, call->fptr); - } - - //code = emit_move_return_value (cfg, ins, code); - - break; - - case OP_FCALL_REG: - case OP_LCALL_REG: - case OP_VCALL_REG: - case OP_VOIDCALL_REG: - case OP_CALL_REG: - { - int offset; - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [fcall_reg/lcall_reg/vcall_reg/voidcall_reg/call_reg]: TargetReg: %d\n", ins->sreg1); - call = (MonoCallInst*)ins; - - alpha_mov1(code, ins->sreg1, alpha_pv); - - alpha_jsr(code, alpha_ra, alpha_pv, 0); - - offset = (char *)code - (char *)cfg->native_code; - - // Restore GP - ALPHA_LOAD_GP(offset) - alpha_ldah(code, alpha_gp, alpha_ra, 0); - alpha_lda(code, alpha_gp, alpha_gp, 0); - } - break; - - case OP_FCALL_MEMBASE: - case OP_CALL_MEMBASE: - case OP_LCALL_MEMBASE: - case OP_VCALL_MEMBASE: - { - int offset; - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [(lvf)call_membase] basereg=%d, offset=%0lx\n", - ins->inst_basereg, ins->inst_offset); - call = (MonoCallInst*)ins; - - alpha_ldq(code, alpha_pv, ins->inst_basereg, ins->inst_offset); - alpha_jsr(code, alpha_ra, alpha_pv, 0); - - offset = (char *)code - (char *)cfg->native_code; - - // Restore GP - ALPHA_LOAD_GP(offset) - alpha_ldah(code, alpha_gp, alpha_ra, 0); - alpha_lda(code, alpha_gp, alpha_gp, 0); - } - break; - - case OP_VOIDCALL_MEMBASE: - { - int offset; - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [voidcall_membase] basereg=%d, offset=%0lx\n", - ins->inst_basereg, ins->inst_offset); - call = (MonoCallInst*)ins; - - alpha_ldq(code, alpha_pv, ins->inst_basereg, ins->inst_offset); - alpha_jsr(code, alpha_ra, alpha_pv, 0); - - offset = (char *)code - (char *)cfg->native_code; - - // Restore GP - ALPHA_LOAD_GP(offset) - alpha_ldah(code, alpha_gp, alpha_ra, 0); - alpha_lda(code, alpha_gp, alpha_gp, 0); - } - break; - - case OP_START_HANDLER: - { - // TODO - find out when we called by call_handler or resume_context - // of by call_filter. There should be difference. For now just - // handle - call_handler - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [start_handler] basereg=%d, offset=%0lx\n", - ins->inst_left->inst_basereg, ins->inst_left->inst_offset); - - alpha_stq(code, alpha_ra, ins->inst_left->inst_basereg, - ins->inst_left->inst_offset); - } - break; - - case OP_ENDFINALLY: - { - // Keep in sync with start_handler - CFG_DEBUG(4) g_print("ALPHA_CHECK: [endfinally] basereg=%d, offset=%0lx\n", - ins->inst_left->inst_basereg, ins->inst_left->inst_offset); - - alpha_ldq(code, alpha_ra, ins->inst_left->inst_basereg, - ins->inst_left->inst_offset); - - alpha_ret(code, alpha_ra, 1); - - } - break; - case OP_ENDFILTER: - { - // Keep in sync with start_handler - CFG_DEBUG(4) g_print("ALPHA_CHECK: [endfilter] sreg1=%d, basereg=%d, offset=%0lx\n", - ins->sreg1, ins->inst_left->inst_basereg, ins->inst_left->inst_offset); - - alpha_ldq(code, alpha_ra, ins->inst_left->inst_basereg, - ins->inst_left->inst_offset); - - if (ins->sreg1 != -1 && ins->sreg1 != alpha_r0) - alpha_mov1(code, ins->sreg1, alpha_r0); - - alpha_ret(code, alpha_ra, 1); - } - break; - - case OP_CALL_HANDLER: - { - int offset; - - offset = (char *)code - (char *)cfg->native_code; - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [call_handler] add patch info: MONO_PATCH_INFO_BB offset: %0X, target_bb: %p]\n", - offset, ins->inst_target_bb); - - mono_add_patch_info (cfg, offset, - MONO_PATCH_INFO_BB, - ins->inst_target_bb); - alpha_bsr(code, alpha_ra, 0); - } - break; - - case OP_THROW: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [throw] sreg1=%0x\n", - ins->sreg1); - alpha_mov1(code, ins->sreg1, alpha_a0); - code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, - (gpointer)"mono_arch_throw_exception"); - break; - - case OP_RETHROW: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [rethrow] sreg1=%0x\n", - ins->sreg1); - alpha_mov1(code, ins->sreg1, alpha_a0); - code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, - (gpointer)"mono_arch_rethrow_exception"); - break; - - case OP_JMP: - { - /* - * Note: this 'frame destruction' logic is useful for tail calls, - too. Keep in sync with the code in emit_epilog. - */ - int offset; - AlphaGotData ge_data; - - CFG_DEBUG(4) g_print("ALPHA_CHECK: [jmp] %p\n", ins->inst_p0); - - /* FIXME: no tracing support... */ - if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE) - code = mono_arch_instrument_epilog (cfg, - mono_profiler_method_leave, code, FALSE); - g_assert (!cfg->method->save_lmf); - - alpha_mov1( code, alpha_fp, alpha_sp ); - - code = emit_load_volatile_arguments (cfg, code); - - offset = cfg->arch.params_stack_size; - - alpha_ldq( code, alpha_ra, alpha_sp, (offset + 0) ); - alpha_ldq( code, alpha_fp, alpha_sp, (offset + 8) ); - alpha_lda( code, alpha_sp, alpha_sp, cfg->arch.stack_size ); - - ge_data.data.p = ins->inst_p0; - add_got_entry(cfg, GT_PTR, ge_data, - (char *)code - (char *)cfg->native_code, - MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0); - alpha_ldq( code, alpha_pv, alpha_gp, 0); - - alpha_jsr( code, alpha_zero, alpha_pv, 0); - } - break; - - case OP_AOTCONST: - mono_add_patch_info (cfg, offset, - (MonoJumpInfoType)ins->inst_i1, ins->inst_p0); - break; - - case OP_MEMORY_BARRIER: - CFG_DEBUG(4) g_print("ALPHA_CHECK: [mb]\n"); - alpha_mb(code); - break; - - case OP_CKFINITE: - // Float register contains a value which we need to check - { - double ni = -1.0 / 0.0; - double pi = 1.0 / 0.0; - AlphaGotData ge_data; - - CFG_DEBUG(4) g_print("ALPHA_TODO: [chfinite] sreg1=%d\n", ins->sreg1); - alpha_cmptun_su(code, ins->sreg1, ins->sreg1, alpha_at); - alpha_trapb(code); - EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException"); - - // Negative infinity - ge_data.data.d = ni; - add_got_entry(cfg, GT_DOUBLE, ge_data, - (char *)code - (char *)cfg->native_code, - MONO_PATCH_INFO_NONE, 0); - alpha_ldt(code, alpha_at, alpha_gp, 0); - - alpha_cmpteq_su(code, ins->sreg1, alpha_at, alpha_at); - alpha_trapb(code); - - EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException"); - - // Positive infinity - ge_data.data.d = pi; - add_got_entry(cfg, GT_DOUBLE, ge_data, - (char *)code - (char *)cfg->native_code, - MONO_PATCH_INFO_NONE, 0); - alpha_ldt(code, alpha_at, alpha_gp, 0); - - alpha_cmpteq_su(code, ins->sreg1, alpha_at, alpha_at); - alpha_trapb(code); - - EMIT_COND_EXC_BRANCH(fbne, alpha_at, "ArithmeticException"); - } - break; - case OP_FDIV: - CFG_DEBUG(4) g_print("ALPHA_TODO: [fdiv] dest=%d, sreg1=%d, sreg2=%d\n", - ins->dreg, ins->sreg1, ins->sreg2); - alpha_divt_su(code, ins->sreg1, ins->sreg2, ins->dreg); - alpha_trapb(code); - - break; - default: - g_warning ("unknown opcode %s in %s()\n", - mono_inst_name (ins->opcode), __FUNCTION__); - alpha_nop(code); - // g_assert_not_reached (); - - } - - if ( (((char *)code) - - ((char *)cfg->native_code) - - offset) > max_len) - { - g_warning ("wrong maximal instruction length of instruction %s (expected %d, got %ld)", - mono_inst_name (ins->opcode), max_len, - ((char *)code) - ((char *)cfg->native_code) - offset ); - //g_assert_not_reached (); - } - - cpos += max_len; - - last_ins = ins; - last_offset = offset; - } - - cfg->code_len = ((char *)code) - ((char *)cfg->native_code); -} - -/*========================= End of Function ========================*/ - - - - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_cpu_optimizations */ -/* */ -/* Function - Returns the optimizations supported on this CPU */ -/* */ -/*------------------------------------------------------------------*/ - -guint32 -mono_arch_cpu_optimizations (guint32 *exclude_mask) -{ - guint32 opts = 0; - - if (getenv("MONO_ALPHA_DEBUG")) - mini_alpha_verbose_level = 1; - - ALPHA_DEBUG("mono_arch_cpu_optimizations"); - - /*----------------------------------------------------------*/ - /* no alpha-specific optimizations yet */ - /*----------------------------------------------------------*/ - *exclude_mask = MONO_OPT_LINEARS; - // *exclude_mask = MONO_OPT_INLINE|MONO_OPT_INLINE; - - return opts; -} -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_cpu_enumerate_simd_versions */ -/* */ -/* Function - Returns the SIMD instruction sets on this CPU */ -/* */ -/*------------------------------------------------------------------*/ -guint32 -mono_arch_cpu_enumerate_simd_versions (void) -{ - /* SIMD is currently unimplemented */ - return 0; -} -/*========================= End of Function ========================*/ - - - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_flush_icache */ -/* */ -/* Function - Flush the CPU icache. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_flush_icache (guint8 *code, gint size) -{ - //ALPHA_DEBUG("mono_arch_flush_icache"); - - /* flush instruction cache to see trampoline code */ - asm volatile("imb":::"memory"); -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_regname */ -/* */ -/* Function - Returns the name of the register specified by */ -/* the input parameter. */ -/* */ -/*------------------------------------------------------------------*/ - -const char* -mono_arch_regname (int reg) { - static const char * rnames[] = { - "alpha_r0", "alpha_r1", "alpha_r2", "alpha_r3", "alpha_r4", - "alpha_r5", "alpha_r6", "alpha_r7", "alpha_r8", "alpha_r9", - "alpha_r10", "alpha_r11", "alpha_r12", "alpha_r13", "alpha_r14", - "alpha_r15", "alpha_r16", "alpha_r17", "alpha_r18", "alpha_r19", - "alpha_r20", "alpha_r21", "alpha_r22", "alpha_r23", "alpha_r24", - "alpha_r25", "alpha_r26", "alpha_r27", "alpha_r28", "alpha_r29", - "alpha_r30", "alpha_r31" - }; - - if (reg >= 0 && reg < 32) - return rnames [reg]; - else - return "unknown"; -} -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_fregname */ -/* */ -/* Function - Returns the name of the register specified by */ -/* the input parameter. */ -/* */ -/*------------------------------------------------------------------*/ - -const char* -mono_arch_fregname (int reg) { - static const char * rnames[] = { - "alpha_f0", "alpha_f1", "alpha_f2", "alpha_f3", "alpha_f4", - "alpha_f5", "alpha_f6", "alpha_f7", "alpha_f8", "alpha_f9", - "alpha_f10", "alpha_f11", "alpha_f12", "alpha_f13", "alpha_f14", - "alpha_f15", "alpha_f16", "alpha_f17", "alpha_f18", "alpha_f19", - "alpha_f20", "alpha_f21", "alpha_f22", "alpha_f23", "alpha_f24", - "alpha_f25", "alpha_f26", "alpha_f27", "alpha_f28", "alpha_f29", - "alpha_f30", "alpha_f31" - }; - - if (reg >= 0 && reg < 32) - return rnames [reg]; - else - return "unknown"; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_patch_code */ -/* */ -/* Function - Process the patch data created during the */ -/* instruction build process. This resolves jumps, */ -/* calls, variables etc. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, - guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors) -{ - MonoJumpInfo *patch_info; - gboolean compile_aot = !run_cctors; - - ALPHA_DEBUG("mono_arch_patch_code"); - - for (patch_info = ji; patch_info; patch_info = patch_info->next) - { - unsigned char *ip = patch_info->ip.i + code; - const unsigned char *target; - - target = mono_resolve_patch_target (method, domain, - code, patch_info, run_cctors); - - if (compile_aot) - { - switch (patch_info->type) - { - - case MONO_PATCH_INFO_BB: - case MONO_PATCH_INFO_LABEL: - break; - default: - /* No need to patch these */ - continue; - } - } - - switch (patch_info->type) - { - case MONO_PATCH_INFO_NONE: - continue; - - case MONO_PATCH_INFO_GOT_OFFSET: - { - unsigned int *ip2 = (unsigned int *)ip; - unsigned int inst = *ip2; - unsigned int off = patch_info->data.offset & 0xFFFFFFFF; - - g_assert(!(off & 0xFFFF8000)); - - inst |= off; - - *ip2 = inst; - } - continue; - - case MONO_PATCH_INFO_CLASS_INIT: - { - /* Might already been changed to a nop */ - unsigned int* ip2 = (unsigned int *)ip; - unsigned long t_addr = (unsigned long)target; - - if (*ip2 != (t_addr & 0xFFFFFFFF) || - *(ip2+1) != ((t_addr>>32) & 0xFFFFFFFF)) - NOT_IMPLEMENTED; - // amd64_call_code (ip2, 0); - break; - } - - // case MONO_PATCH_INFO_METHOD_REL: - case MONO_PATCH_INFO_R8: - case MONO_PATCH_INFO_R4: - g_assert_not_reached (); - continue; - case MONO_PATCH_INFO_BB: - break; - - case MONO_PATCH_INFO_METHOD: - case MONO_PATCH_INFO_METHODCONST: - case MONO_PATCH_INFO_INTERNAL_METHOD: - case MONO_PATCH_INFO_METHOD_JUMP: - { - volatile unsigned int *p = (unsigned int *)ip; - unsigned long t_addr; - - t_addr = *(p+1); - t_addr <<= 32; - t_addr |= *(p); - - ALPHA_PRINT - g_debug("ALPHA_PATCH: MONO_PATCH_INFO_METHOD(CONST) calc target: %p, stored target: %0lX", - target, t_addr); - if (target != ((void *)t_addr)) - { - t_addr = (unsigned long)target; - *p = (unsigned int)(t_addr & 0xFFFFFFFF); - *(p+1) = (unsigned int)((t_addr >> 32) & 0xFFFFFFFF); - } - } - continue; - - case MONO_PATCH_INFO_ABS: - { - volatile unsigned int *p = (unsigned int *)ip; - unsigned long t_addr; - - t_addr = *(p+1); - t_addr <<= 32; - t_addr += *(p); - - ALPHA_PRINT g_debug("ALPHA_PATCH: MONO_PATCH_INFO_ABS calc target: %p, stored target: %0lX", - target, t_addr); - - } - continue; - case MONO_PATCH_INFO_SWITCH: - { - unsigned int *pcode = (unsigned int *)ip; - unsigned long t_addr; - - t_addr = (unsigned long)target; - - if (((unsigned long)ip) % 8) - { - alpha_nop(pcode); - ip += 4; - } - - //alpha_ldq(pcode, alpha_at, alpha_gp, (ip - code + 8)); - alpha_nop(pcode); // TODO optimize later - alpha_bsr(pcode, alpha_at, 2); - - *pcode = (unsigned int)(t_addr & 0xFFFFFFFF); - pcode++; - *pcode = (unsigned int)((t_addr >> 32) & 0xFFFFFFFF); - pcode++; - - alpha_ldq(pcode, alpha_at, alpha_at, 0); - - } - continue; - - default: - break; - } - - { - volatile unsigned int *p = (unsigned int *)ip; - unsigned int alpha_ins = *p; - unsigned int opcode; - long br_offset; - - opcode = (alpha_ins >> AXP_OP_SHIFT) & AXP_OFF6_MASK; - - if (opcode >= 0x30 && opcode <= 0x3f) - { - // This is branch with offset instruction - br_offset = (target - ip - 4); - - g_assert(!(br_offset & 3)); - - alpha_ins |= (br_offset/4) & AXP_OFF21_MASK; - - *p = alpha_ins; - } - } - } -} - -/*========================= End of Function ========================*/ -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_emit_this_vret_args */ -/* */ -/* Function - */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, - int this_reg, int this_type, int vt_reg) -{ - MonoCallInst *call = (MonoCallInst*)inst; - CallInfo * cinfo = get_call_info (cfg->generic_sharing_context, inst->signature, FALSE); - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_emit_this_vret_args"); - - if (vt_reg != -1) - { - MonoInst *vtarg; - - if (cinfo->ret.storage == ArgValuetypeInReg) - { - /* - * The valuetype is in RAX:RDX after the call, need to be copied to - * the stack. Push the address here, so the call instruction can - * access it. - */ - //MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH); - //vtarg->sreg1 = vt_reg; - //mono_bblock_add_inst (cfg->cbb, vtarg); - - /* Align stack */ - //MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_E - // SP, 8); - } - else - { - MONO_INST_NEW (cfg, vtarg, OP_MOVE); - vtarg->sreg1 = vt_reg; - vtarg->dreg = mono_alloc_ireg (cfg); - mono_bblock_add_inst (cfg->cbb, vtarg); - - mono_call_inst_add_outarg_reg (cfg, call, vtarg->dreg, - cinfo->ret.reg, FALSE); - } - } - - /* add the this argument */ - if (this_reg != -1) - { - MonoInst *this; - MONO_INST_NEW (cfg, this, OP_MOVE); - this->type = this_type; - this->sreg1 = this_reg; - this->dreg = mono_alloc_ireg (cfg); - mono_bblock_add_inst (cfg->cbb, this); - - mono_call_inst_add_outarg_reg (cfg, call, this->dreg, - cinfo->args [0].reg, FALSE); - } - - g_free (cinfo); -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_is_inst_imm */ -/* */ -/* Function - Determine if operand qualifies as an immediate */ -/* value. For Alpha this is a value 0 - 255 */ -/* */ -/* Returns - True|False - is [not] immediate value. */ -/* */ -/*------------------------------------------------------------------*/ - -gboolean -mono_arch_is_inst_imm (gint64 imm) -{ -// ALPHA_DEBUG("mono_arch_is_inst_imm"); - - return (imm & ~(0x0FFL)) ? 0 : 1; -} - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_finish_init */ -/* */ -/* Function - Setup the JIT's Thread Level Specific Data. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_finish_init (void) -{ - ALPHA_DEBUG("mono_arch_finish_init"); - - if (!lmf_addr_key_inited) { - lmf_addr_key_inited = TRUE; - pthread_key_create (&lmf_addr_key, NULL); - } - - pthread_setspecific (lmf_addr_key, &tls->lmf); -} - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_cpu_init */ -/* */ -/* Function - Perform CPU specific initialization to execute */ -/* managed code. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_cpu_init (void) -{ - unsigned long amask, implver; - register long v0 __asm__("$0") = -1; - - ALPHA_DEBUG("mono_arch_cpu_init"); - - __asm__ (".long 0x47e00c20" : "=r"(v0) : "0"(v0)); - amask = ~v0; - __asm__ (".long 0x47e03d80" : "=r"(v0)); - implver = v0; - - if (amask & 1) - bwx_supported = 1; - - //printf("amask: %x, implver: %x", amask, implver); -} - -/* - * Initialize architecture specific code. - */ -void -mono_arch_init (void) -{ -} - -/* - * Cleanup architecture specific code. - */ -void -mono_arch_cleanup (void) -{ -} - -/* - * get_call_info: - * - * Obtain information about a call according to the calling convention. - * - * For x86 ELF, see the "System V Application Binary Interface Intel386 - * Architecture Processor Supplment, Fourth Edition" document for more - * information. - * For x86 win32, see ???. - */ -static CallInfo* -get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gboolean is_pinvoke) -{ - guint32 i, gr, fr, *pgr, *pfr; - MonoType *ret_type; - int n = sig->hasthis + sig->param_count; - guint32 stack_size = 0; - CallInfo *cinfo; - - cinfo = g_malloc0 (sizeof (CallInfo) + (sizeof (ArgInfo) * n)); - - gr = 0; - fr = 0; - - if (is_pinvoke) - pgr = pfr = &gr; - else - { - pgr = &gr; - pfr = &fr; - } - - /* return value */ - { - ret_type = mono_type_get_underlying_type (sig->ret); - switch (ret_type->type) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_FNPTR: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - case MONO_TYPE_STRING: - cinfo->ret.storage = ArgInIReg; - cinfo->ret.reg = alpha_r0; - break; - case MONO_TYPE_U8: - case MONO_TYPE_I8: - cinfo->ret.storage = ArgInIReg; - cinfo->ret.reg = alpha_r0; - break; - case MONO_TYPE_R4: - cinfo->ret.storage = ArgInFloatReg; - cinfo->ret.reg = alpha_f0; - break; - case MONO_TYPE_R8: - cinfo->ret.storage = ArgInDoubleReg; - cinfo->ret.reg = alpha_f0; - break; - case MONO_TYPE_GENERICINST: - if (!mono_type_generic_inst_is_valuetype (ret_type)) - { - cinfo->ret.storage = ArgInIReg; - cinfo->ret.reg = alpha_r0; - break; - } - /* Fall through */ - case MONO_TYPE_VALUETYPE: - { - guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0; - - add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE, - &tmp_gr, &tmp_fr, &tmp_stacksize); - - if (cinfo->ret.storage == ArgOnStack) - /* The caller passes the address where the value - is stored */ - add_general (pgr, &stack_size, &cinfo->ret); - break; - } - case MONO_TYPE_TYPEDBYREF: - /* Same as a valuetype with size 24 */ - add_general (pgr, &stack_size, &cinfo->ret); - ; - break; - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - } - - /* this */ - if (sig->hasthis) - add_general (pgr, &stack_size, cinfo->args + 0); - - if (!sig->pinvoke && - (sig->call_convention == MONO_CALL_VARARG) && (n == 0)) - { - gr = PARAM_REGS; - fr = FLOAT_PARAM_REGS; - - /* Emit the signature cookie just before the implicit arguments - */ - add_general (pgr, &stack_size, &cinfo->sig_cookie); - } - - for (i = 0; i < sig->param_count; ++i) - { - ArgInfo *ainfo = &cinfo->args [sig->hasthis + i]; - MonoType *ptype; - - if (!sig->pinvoke && - (sig->call_convention == MONO_CALL_VARARG) && - (i == sig->sentinelpos)) - { - /* We allways pass the sig cookie on the stack for simpl - icity */ - /* - * Prevent implicit arguments + the sig cookie from being passed - * in registers. - */ - gr = PARAM_REGS; - fr = FLOAT_PARAM_REGS; - - /* Emit the signature cookie just before the implicit arguments */ - add_general (pgr, &stack_size, &cinfo->sig_cookie); - } - - if (sig->params [i]->byref) { - add_general (pgr, &stack_size, ainfo); - continue; - } - - ptype = mono_type_get_underlying_type (sig->params [i]); - - switch (ptype->type) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - add_general (pgr, &stack_size, ainfo); - break; - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - add_general (pgr, &stack_size, ainfo); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - add_general (pgr, &stack_size, ainfo); - break; - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_FNPTR: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - add_general (pgr, &stack_size, ainfo); - break; - case MONO_TYPE_GENERICINST: - if (!mono_type_generic_inst_is_valuetype (ptype)) - { - add_general (pgr, &stack_size, ainfo); - break; - } - /* Fall through */ - case MONO_TYPE_VALUETYPE: - /* FIXME: */ - /* We allways pass valuetypes on the stack */ - add_valuetype (gsctx, sig, ainfo, sig->params [i], - FALSE, pgr, pfr, &stack_size); - break; - case MONO_TYPE_TYPEDBYREF: - stack_size += sizeof (MonoTypedRef); - ainfo->storage = ArgOnStack; - break; - case MONO_TYPE_U8: - case MONO_TYPE_I8: - add_general (pgr, &stack_size, ainfo); - break; - case MONO_TYPE_R4: - add_float (pfr, &stack_size, ainfo, FALSE); - break; - case MONO_TYPE_R8: - add_float (pfr, &stack_size, ainfo, TRUE); - break; - default: - g_assert_not_reached (); - } - } - - if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && - (n > 0) && (sig->sentinelpos == sig->param_count)) - { - gr = PARAM_REGS; - fr = FLOAT_PARAM_REGS; - - /* Emit the signature cookie just before the implicit arguments - */ - add_general (pgr, &stack_size, &cinfo->sig_cookie); - } - - cinfo->stack_usage = stack_size; - cinfo->reg_usage = gr; - cinfo->freg_usage = fr; - - return cinfo; -} - -static const char *CvtMonoType(MonoTypeEnum t) -{ - switch(t) - { - case MONO_TYPE_END: - return "MONO_TYPE_END"; - case MONO_TYPE_VOID: - return "MONO_TYPE_VOID"; - case MONO_TYPE_BOOLEAN: - return "MONO_TYPE_BOOLEAN"; - case MONO_TYPE_CHAR: - return "MONO_TYPE_CHAR"; - case MONO_TYPE_I1: - return "MONO_TYPE_I1"; - case MONO_TYPE_U1: - return "MONO_TYPE_U1"; - case MONO_TYPE_I2: - return "MONO_TYPE_I2"; - case MONO_TYPE_U2: - return "MONO_TYPE_U2"; - case MONO_TYPE_I4: - return "MONO_TYPE_I4"; - case MONO_TYPE_U4: - return "MONO_TYPE_U4"; - case MONO_TYPE_I8: - return "MONO_TYPE_I8"; - case MONO_TYPE_U8: - return "MONO_TYPE_U8"; - case MONO_TYPE_R4: - return "MONO_TYPE_R4"; - case MONO_TYPE_R8: - return "MONO_TYPE_R8"; - case MONO_TYPE_STRING: - return "MONO_TYPE_STRING"; - case MONO_TYPE_PTR: - return "MONO_TYPE_PTR"; - case MONO_TYPE_BYREF: - return "MONO_TYPE_BYREF"; - case MONO_TYPE_VALUETYPE: - return "MONO_TYPE_VALUETYPE"; - case MONO_TYPE_CLASS: - return "MONO_TYPE_CLASS"; - case MONO_TYPE_VAR: - return "MONO_TYPE_VAR"; - case MONO_TYPE_ARRAY: - return "MONO_TYPE_ARRAY"; - case MONO_TYPE_GENERICINST: - return "MONO_TYPE_GENERICINST"; - case MONO_TYPE_TYPEDBYREF: - return "MONO_TYPE_TYPEDBYREF"; - case MONO_TYPE_I: - return "MONO_TYPE_I"; - case MONO_TYPE_U: - return "MONO_TYPE_U"; - case MONO_TYPE_FNPTR: - return "MONO_TYPE_FNPTR"; - case MONO_TYPE_OBJECT: - return "MONO_TYPE_OBJECT"; - case MONO_TYPE_SZARRAY: - return "MONO_TYPE_SZARRAY"; - case MONO_TYPE_MVAR: - return "MONO_TYPE_MVAR"; - case MONO_TYPE_CMOD_REQD: - return "MONO_TYPE_CMOD_REQD"; - case MONO_TYPE_CMOD_OPT: - return "MONO_TYPE_CMOD_OPT"; - case MONO_TYPE_INTERNAL: - return "MONO_TYPE_INTERNAL"; - case MONO_TYPE_MODIFIER: - return "MONO_TYPE_MODIFIER"; - case MONO_TYPE_SENTINEL: - return "MONO_TYPE_SENTINEL"; - case MONO_TYPE_PINNED: - return "MONO_TYPE_PINNED"; - default: - ; - } - return "unknown"; -} - - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_call_opcode */ -/* */ -/* Function - Take the arguments and generate the arch-specific */ -/* instructions to properly call the function. This */ -/* includes pushing, moving argments to the correct */ -/* etc. */ -/* - * This method is called during converting method to IR - * We need to generate IR ints to follow calling convention - * cfg - points to currently compiled unit - * bb - ??? - * call - points to structure that describes what we are going to - * call (at least number of parameters required for the call) - * - * - * On return we need to pass back modified call structure - */ -/*------------------------------------------------------------------*/ - -MonoCallInst* -mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, - MonoCallInst *call, int is_virtual) -{ - MonoInst *arg, *in; - MonoMethodSignature *sig; - int i, n; - CallInfo *cinfo; - int sentinelpos; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_call_opcode"); - - sig = call->signature; - n = sig->param_count + sig->hasthis; - - // Collect info about method we age going to call - cinfo = get_call_info (cfg->generic_sharing_context, sig, sig->pinvoke); - - CFG_DEBUG(3) g_print("ALPHA: Will call %s method with %d(%d) params. RetType: %s(0x%X)\n", - sig->pinvoke ? "PInvoke" : "Managed", - sig->param_count, sig->hasthis, - CvtMonoType(sig->ret->type), sig->ret->type); - - if (cinfo->stack_usage > cfg->arch.params_stack_size) - cfg->arch.params_stack_size = cinfo->stack_usage; - - if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG)) - sentinelpos = sig->sentinelpos + (is_virtual ? 1 : 0); - - for (i = 0; i < n; ++i) - { - ArgInfo *ainfo = cinfo->args + i; - - /* Emit the signature cookie just before the implicit arguments - */ - if (!sig->pinvoke && - (sig->call_convention == MONO_CALL_VARARG) && - (i == sentinelpos)) - { - MonoMethodSignature *tmp_sig; - MonoInst *sig_arg; - - /* FIXME: Add support for signature tokens to AOT */ - cfg->disable_aot = TRUE; - MONO_INST_NEW (cfg, arg, OP_OUTARG); - - /* - * mono_ArgIterator_Setup assumes the signature cookie is - * passed first and all the arguments which were before it are - * passed on the stack after the signature. So compensate by - * passing a different signature. - */ - tmp_sig = mono_metadata_signature_dup (call->signature); - tmp_sig->param_count -= call->signature->sentinelpos; - tmp_sig->sentinelpos = 0; - memcpy (tmp_sig->params, - call->signature->params + call->signature->sentinelpos, - tmp_sig->param_count * sizeof (MonoType*)); - - MONO_INST_NEW (cfg, sig_arg, OP_ICONST); - sig_arg->inst_p0 = tmp_sig; - - MONO_INST_NEW (cfg, arg, OP_OUTARG); - arg->inst_left = sig_arg; - arg->type = STACK_PTR; - - /* prepend, so they get reversed */ - arg->next = call->out_args; - call->out_args = arg; - } - - if (is_virtual && i == 0) { - /* the argument will be attached to the call instrucion - */ - in = call->args [i]; - } else { - MonoType *arg_type; - - MONO_INST_NEW (cfg, arg, OP_OUTARG); - in = call->args [i]; - arg->cil_code = in->cil_code; - arg->inst_left = in; - arg->type = in->type; - /* prepend, so they get reversed */ - arg->next = call->out_args; - call->out_args = arg; - - CFG_DEBUG(3) g_print("ALPHA: Param[%d] - ", i); - - if (sig->hasthis && (i == 0)) - arg_type = &mono_defaults.object_class->byval_arg; - else - arg_type = sig->params [i - sig->hasthis]; - - if ((i >= sig->hasthis) && - (MONO_TYPE_ISSTRUCT(arg_type))) - { - guint align; - guint32 size; - - if (arg_type->type == MONO_TYPE_TYPEDBYREF) { - size = sizeof (MonoTypedRef); - align = sizeof (gpointer); - } - else - if (sig->pinvoke) - size = mono_type_native_stack_size (&in->klass->byval_arg, - &align); - else - size = mini_type_stack_size (cfg->generic_sharing_context, &in->klass->byval_arg, &align); - - if (ainfo->storage == ArgAggregate) - { - MonoInst *vtaddr, *load, *load2, *offset_ins, *set_reg; - int slot, j; - - CFG_DEBUG(3) g_print("aggregate value type, size:%d\n", size); - - vtaddr = mono_compile_create_var (cfg, - &mono_defaults.int_class->byval_arg, OP_LOCAL); - - /* - * Part of the structure is passed in registers. - */ - for (j = 0; j < ainfo->nregs; ++j) - { - int offset, load_op, dest_reg, arg_storage; - - slot = ainfo->reg + j; - load_op = CEE_LDIND_I; - offset = j * 8; - dest_reg = ainfo->reg + j; - arg_storage = ArgInIReg; - - MONO_INST_NEW (cfg, load, CEE_LDIND_I); - load->ssa_op = MONO_SSA_LOAD; - load->inst_i0 = (cfg)->varinfo [vtaddr->inst_c0]; - - NEW_ICONST (cfg, offset_ins, offset); - MONO_INST_NEW (cfg, load2, CEE_ADD); - load2->inst_left = load; - load2->inst_right = offset_ins; - - MONO_INST_NEW (cfg, load, load_op); - load->inst_left = load2; - - if (j == 0) - set_reg = arg; - else - MONO_INST_NEW (cfg, set_reg, OP_OUTARG_REG); - - add_outarg_reg (cfg, call, set_reg, arg_storage, - dest_reg, load); - if (set_reg != call->out_args) - { - set_reg->next = call->out_args; - call->out_args = set_reg; - } - } - - /* - * Part of the structure is passed on the stack. - */ - for (j = ainfo->nregs; j < ainfo->nslots; ++j) - { - MonoInst *outarg; - - slot = ainfo->reg + j; - - MONO_INST_NEW (cfg, load, CEE_LDIND_I); - load->ssa_op = MONO_SSA_LOAD; - load->inst_i0 = (cfg)->varinfo [vtaddr->inst_c0]; - - NEW_ICONST (cfg, offset_ins, (j * sizeof (gpointer))); - MONO_INST_NEW (cfg, load2, CEE_ADD); - load2->inst_left = load; - load2->inst_right = offset_ins; - - MONO_INST_NEW (cfg, load, CEE_LDIND_I); - load->inst_left = load2; - - if (j == 0) - outarg = arg; - else - MONO_INST_NEW (cfg, outarg, OP_OUTARG); - - outarg->inst_left = load; - //outarg->inst_imm = 16 + ainfo->offset + (slot - 8) * 8; - outarg->dreg = ainfo->offset + (slot - 22) * 8; - - if (outarg != call->out_args) - { - outarg->next = call->out_args; - call->out_args = outarg; - } - } - - /* Trees can't be shared so make a copy*/ - MONO_INST_NEW (cfg, arg, CEE_STIND_I); - arg->cil_code = in->cil_code; - arg->ssa_op = MONO_SSA_STORE; - arg->inst_left = vtaddr; - arg->inst_right = in; - arg->type = in->type; - - /* prepend, so they get reversed */ - arg->next = call->out_args; - call->out_args = arg; - } - else - { - MonoInst *stack_addr; - - CFG_DEBUG(3) g_print("value type, size:%d\n", size); - - MONO_INST_NEW (cfg, stack_addr, OP_REGOFFSET); - stack_addr->inst_basereg = alpha_sp; - //stack_addr->inst_offset = -(cinfo->stack_usage - ainfo->offset); - stack_addr->inst_offset = ainfo->offset; - //stack_addr->inst_offset = 16 + ainfo->offset; - stack_addr->inst_imm = size; - - arg->opcode = OP_OUTARG_VT; - arg->inst_right = stack_addr; - } - - /* - arg->opcode = OP_OUTARG_VT; - arg->klass = in->klass; - arg->backend.is_pinvoke = sig->pinvoke; - arg->inst_imm = size; */ - } - else - { - CFG_DEBUG(3) g_print("simple\n"); - - switch (ainfo->storage) - { - case ArgInIReg: - add_outarg_reg (cfg, call, arg, ainfo->storage, - ainfo->reg, in); - break; - case ArgOnStack: - arg->opcode = OP_OUTARG; - //arg->dreg = -((n - i) * 8); - arg->dreg = ainfo->offset; - //arg->inst_left->inst_imm = (n - i - 1) * 8; - - if (!sig->params[i-sig->hasthis]->byref) { - if (sig->params[i-sig->hasthis]->type == MONO_TYPE_R4) - arg->opcode = OP_OUTARG_R4; - else - if (sig->params[i-sig->hasthis]->type == MONO_TYPE_R8) - arg->opcode = OP_OUTARG_R8; - } - break; - case ArgInFloatReg: - case ArgInDoubleReg: - add_outarg_reg (cfg, call, arg, ainfo->storage, ainfo->reg, in); - break; - default: - g_assert_not_reached (); - } - } - } - } - - if (sig->ret && MONO_TYPE_ISSTRUCT (sig->ret)) - { - if (cinfo->ret.storage == ArgValuetypeInReg) { - MonoInst *zero_inst; - /* - * After the call, the struct is in registers, but needs to be saved - to the memory pointed - * to by vt_arg in this_vret_args. This means that vt_ar - g needs to be saved somewhere - * before calling the function. So we add a dummy instru - ction to represent pushing the - * struct return address to the stack. The return addres - s will be saved to this stack slot - * by the code emitted in this_vret_args. - */ - MONO_INST_NEW (cfg, arg, OP_OUTARG); - MONO_INST_NEW (cfg, zero_inst, OP_ICONST); - zero_inst->inst_p0 = 0; - arg->inst_left = zero_inst; - arg->type = STACK_PTR; - /* prepend, so they get reversed */ - arg->next = call->out_args; - call->out_args = arg; - } - else - /* if the function returns a struct, the called method a - lready does a ret $0x4 */ - if (sig->ret && MONO_TYPE_ISSTRUCT (sig->ret)) - ; //cinfo->stack_usage -= 4; - } - - // stack_usage shows how much stack we would need to do the call - // (for example for params that we pass on stack - call->stack_usage = cinfo->stack_usage; - - // Save all used regs to do the call in compile unit structure - cfg->used_int_regs |= call->used_iregs; - - g_free (cinfo); - - return call; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_register_lowlevel_calls */ -/* */ -/* Function - Register routines to help with --trace operation. */ -/* */ -/*------------------------------------------------------------------*/ - -void -mono_arch_register_lowlevel_calls (void) -{ - ALPHA_DEBUG("mono_arch_register_lowlevel_calls"); - - mono_register_jit_icall (mono_arch_get_lmf_addr, "mono_arch_get_lmf_addr", - NULL, TRUE); -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_global_int_regs */ -/* */ -/* Function - Return a list of usable integer registers. */ -/* */ -/*------------------------------------------------------------------*/ - -GList * -mono_arch_get_global_int_regs (MonoCompile *cfg) -{ - GList *regs = NULL; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_get_global_int_regs"); - -// regs = g_list_prepend (regs, (gpointer)alpha_r9); -// regs = g_list_prepend (regs, (gpointer)alpha_r10); -// regs = g_list_prepend (regs, (gpointer)alpha_r11); - regs = g_list_prepend (regs, (gpointer)alpha_r12); - regs = g_list_prepend (regs, (gpointer)alpha_r13); - regs = g_list_prepend (regs, (gpointer)alpha_r14); - - return regs; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_get_allocatable_int_vars */ -/* */ -/* Function - */ -/* */ -/*------------------------------------------------------------------*/ - -GList * -mono_arch_get_allocatable_int_vars (MonoCompile *cfg) -{ - GList *vars = NULL; - int i; - MonoMethodSignature *sig; - MonoMethodHeader *header; - CallInfo *cinfo; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_get_allocatable_int_vars"); - - header = cfg->header; - - sig = mono_method_signature (cfg->method); - - cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE); - - for (i = 0; i < sig->param_count + sig->hasthis; ++i) - { - MonoInst *ins = cfg->args [i]; - - ArgInfo *ainfo = &cinfo->args [i]; - - if (ins->flags & - (MONO_INST_IS_DEAD|MONO_INST_VOLATILE|MONO_INST_INDIRECT)) - continue; - - // if (ainfo->storage == ArgInIReg) { - // /* The input registers are non-volatile */ - // ins->opcode = OP_REGVAR; - //ins->dreg = 32 + ainfo->reg; - // } - } - - for (i = 0; i < cfg->num_varinfo; i++) - { - MonoInst *ins = cfg->varinfo [i]; - MonoMethodVar *vmv = MONO_VARINFO (cfg, i); - - /* unused vars */ - if (vmv->range.first_use.abs_pos >= vmv->range.last_use.abs_pos) - continue; - - if ((ins->flags & - (MONO_INST_IS_DEAD|MONO_INST_VOLATILE|MONO_INST_INDIRECT)) || - (ins->opcode != OP_LOCAL && ins->opcode != OP_ARG)) - continue; - - if (mono_is_regsize_var (ins->inst_vtype)) - { - g_assert (MONO_VARINFO (cfg, i)->reg == -1); - g_assert (i == vmv->idx); - vars = g_list_prepend (vars, vmv); - } - } - - vars = mono_varlist_sort (cfg, vars, 0); - - return vars; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_get_domain_intrinsic */ -/* */ -/* Function - */ -/* */ -/* Returns - */ -/* */ -/*------------------------------------------------------------------*/ - -MonoInst * -mono_arch_get_domain_intrinsic (MonoCompile* cfg) -{ - MonoInst *ins; - - if (appdomain_tls_offset == -1) - return NULL; - - MONO_INST_NEW (cfg, ins, OP_TLS_GET); - ins->inst_offset = appdomain_tls_offset; - return (ins); -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_get_inst_for_method */ -/* */ -/* Function - Check for opcodes we can handle directly in */ -/* hardware. */ -/* */ -/*------------------------------------------------------------------*/ - -MonoInst* -mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, - MonoMethodSignature *fsig, MonoInst **args) -{ - MonoInst *ins = NULL; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_get_inst_for_method"); - - CFG_DEBUG(3) g_print("mono_arch_get_inst_for_method: %s\n", cmethod->name); - - return ins; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_create_class_init_trampoline */ -/* */ -/* Function - Creates a trampoline function to run a type init- */ -/* ializer. If the trampoline is called, it calls */ -/* mono_runtime_class_init with the given vtable, */ -/* then patches the caller code so it does not get */ -/* called any more. */ -/* */ -/* Parameter - vtable - The type to initialize */ -/* */ -/* Returns - A pointer to the newly created code */ -/* */ -/*------------------------------------------------------------------*/ - -gpointer -mono_arch_create_class_init_trampoline (MonoVTable *vtable) -{ - ALPHA_DEBUG("mono_arch_create_class_init_trampoline"); - - NOT_IMPLEMENTED; - - return 0; -} - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_instrument_prolog */ -/* */ -/* Function - Create an "instrumented" prolog. */ -/* */ -/*------------------------------------------------------------------*/ - -void* -mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p, - gboolean enable_arguments) -{ - unsigned int *code = p; - int offset; - - CallInfo *cinfo = NULL; - MonoMethodSignature *sig; - MonoInst *inst; - int i, n, stack_area = 0; - AlphaGotData ge_data; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_instrument_prolog"); - - /* Keep this in sync with mono_arch_get_argument_info */ - if (enable_arguments) - { - /* Allocate a new area on the stack and save arguments there */ - sig = mono_method_signature (cfg->method); - - cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE); - - n = sig->param_count + sig->hasthis; - - stack_area = ALIGN_TO (n * 8, 8); - - // Correct stack by calculated value - if (stack_area) - alpha_lda(code, alpha_sp, alpha_sp, -stack_area); - - for (i = 0; i < n; ++i) - { - inst = cfg->args [i]; - - if (inst->opcode == OP_REGVAR) - { - switch(cinfo->args[i].storage) - { - case ArgInDoubleReg: - alpha_stt(code, inst->dreg, alpha_sp, (i*8)); - break; - case ArgInFloatReg: - alpha_sts(code, inst->dreg, alpha_sp, (i*8)); - break; - default: - alpha_stq(code, inst->dreg, alpha_sp, (i*8)); - } - } - else - { - alpha_ldq(code, alpha_at, inst->inst_basereg, inst->inst_offset); - alpha_stq(code, alpha_at, alpha_sp, (i*8)); - } - } - } - - offset = (char *)code - (char *)cfg->native_code; - - ge_data.data.p = cfg->method; - - add_got_entry(cfg, GT_PTR, ge_data, - (char *)code - (char *)cfg->native_code, - MONO_PATCH_INFO_METHODCONST, cfg->method); - alpha_ldq(code, alpha_a0, alpha_gp, 0); - - alpha_mov1(code, alpha_sp, alpha_a1); - - code = emit_call(cfg, code, MONO_PATCH_INFO_ABS, (gpointer)func); - - if (enable_arguments) - { - // Correct stack back by calculated value - if (stack_area) - alpha_lda(code, alpha_sp, alpha_sp, stack_area); - - g_free(cinfo); - } - - return code; -} - -/*========================= End of Function ========================*/ - -enum { - SAVE_NONE, - SAVE_STRUCT, - SAVE_R0, - SAVE_EAX_EDX, - SAVE_XMM -}; - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_instrument_epilog */ -/* */ -/* Function - Create an epilog that will handle the returned */ -/* values used in instrumentation. */ -/* */ -/*------------------------------------------------------------------*/ - -void* -mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments, gboolean preserve_argument_registers) -{ - unsigned int *code = p; - int save_mode = SAVE_NONE; - int offset; - MonoMethod *method = cfg->method; - AlphaGotData ge_data; - int rtype = mono_type_get_underlying_type (mono_method_signature (method)->ret)->type; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_instrument_epilog"); - - switch (rtype) - { - case MONO_TYPE_VOID: - /* special case string .ctor icall */ - if (strcmp (".ctor", method->name) && - method->klass == mono_defaults.string_class) - save_mode = SAVE_R0; - else - save_mode = SAVE_NONE; - break; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - save_mode = SAVE_R0; - break; - case MONO_TYPE_R4: - case MONO_TYPE_R8: - save_mode = SAVE_XMM; - break; - case MONO_TYPE_VALUETYPE: - save_mode = SAVE_STRUCT; - break; - default: - save_mode = SAVE_R0; - break; - } - - /* Save the result and copy it into the proper argument register */ - switch (save_mode) - { - case SAVE_R0: - alpha_lda(code, alpha_sp, alpha_sp, -8); - alpha_stq(code, alpha_r0, alpha_sp, 0); - - if (enable_arguments) - alpha_mov1(code, alpha_r0, alpha_a1); - - break; - case SAVE_STRUCT: - /* FIXME: */ - if (enable_arguments) - alpha_lda(code, alpha_a1, alpha_zero, 0); - - break; - case SAVE_XMM: - //amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 8); - //amd64_movsd_membase_reg (code, AMD64_RSP, 0, AMD64_XMM0); - /* Align stack */ - //amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 8); - /* - * The result is already in the proper argument register so no copying - * needed. - */ - break; - case SAVE_NONE: - break; - default: - g_assert_not_reached (); - } - - offset = (char *)code - (char *)cfg->native_code; - - ge_data.data.p = cfg->method; - - add_got_entry(cfg, GT_PTR, ge_data, - (char *)code - (char *)cfg->native_code, - MONO_PATCH_INFO_METHODCONST, cfg->method); - - alpha_ldq(code, alpha_a0, alpha_gp, 0); - - code = emit_call(cfg, code, MONO_PATCH_INFO_ABS, (gpointer)func); - - /* Restore result */ - switch (save_mode) - { - case SAVE_R0: - alpha_ldq(code, alpha_r0, alpha_sp, 0); - alpha_lda(code, alpha_sp, alpha_sp, 8); - break; - case SAVE_STRUCT: - /* FIXME: */ - break; - case SAVE_XMM: - //amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 8); - //amd64_movsd_reg_membase (code, AMD64_XMM0, AMD64_RSP, 0); - //amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 8); - break; - case SAVE_NONE: - break; - default: - g_assert_not_reached (); - } - - return code; -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_allocate_vars */ -/* */ -/* Function - Set var information according to the calling */ -/* convention for Alpha. The local var stuff should */ -/* most likely be split in another method. */ -/* */ -/* Parameter - @m - Compile unit. */ -/* - * This method is called right before working with BBs. Conversion to - * IR was done and some analises what registers would be used. - * Collect info about registers we used - if we want to use a register - * we need to allocate space for it and save on the stack in method - * prolog. - * - * Alpha calling convertion: - * FP -> Stack top <- SP - * 0: Stack params to call others - * - * RA <- arch.params_stack_size - * old FP - * - * [LMF info] <- arch.lmf_offset - * . - * [possible return values allocated on stack] - * - * . [locals] - * . - * . caller saved regs <- arch.reg_save_area_offset - * . a0 <- arch.args_save_area_offset - * . a1 - * . a2 - * . a3 - * . a4 - * . a5 - * ------------------------ - * . a6 - passed args on stack - * . - */ -/*------------------------------------------------------------------*/ - -void -mono_arch_allocate_vars (MonoCompile *cfg) -{ - MonoMethodSignature *sig; - MonoMethodHeader *header; - MonoInst *inst; - int i, offset = 0, a_off = 0; - guint32 locals_stack_size, locals_stack_align = 0; - gint32 *offsets; - CallInfo *cinfo; - - CFG_DEBUG(2) ALPHA_DEBUG("mono_arch_allocate_vars"); - - header = cfg->header; - - sig = mono_method_signature (cfg->method); - - cinfo = get_call_info (cfg->generic_sharing_context, sig, FALSE); - - /* if (cfg->arch.omit_fp) { - cfg->flags |= MONO_CFG_HAS_SPILLUP; - cfg->frame_reg = AMD64_RSP; - offset = 0; - } - else */ - { - /* Locals are allocated forwards from FP. After - * RA (offset 0), FP (offset 8) and ret value, locals, A0-A5 - * (starting from offset 16). - * FIXME: Check there Arg6...Argn are supposed to be - */ - cfg->frame_reg = alpha_fp; - // offset = MONO_ALPHA_VARS_OFFSET; - } - - CFG_DEBUG(3) g_print ("ALPHA: Size for call params is %d(%x)\n", - cfg->arch.params_stack_size, cfg->arch.params_stack_size); - offset += cfg->arch.params_stack_size; - - offset += 16; // Size to save RA & FP - - if (cfg->method->save_lmf) - { - /* Reserve stack space for saving LMF + argument regs */ - guint32 size = sizeof (MonoLMF); - - //if (lmf_tls_offset == -1) - // /* Need to save argument regs too */ - // size += (AMD64_NREG * 8) + (8 * 8); - - cfg->arch.lmf_offset = offset; - offset += size; - - CFG_DEBUG(3) g_print ("ALPHA: Method %s needs LMF. Offset: %x, Size: %x\n", - cfg->method->name, cfg->arch.lmf_offset, size); - } - - if (sig->ret->type != MONO_TYPE_VOID) - { - switch (cinfo->ret.storage) - { - case ArgInIReg: - case ArgInFloatReg: - case ArgInDoubleReg: - if ((MONO_TYPE_ISSTRUCT (sig->ret) && - !mono_class_from_mono_type (sig->ret)->enumtype) || - (sig->ret->type == MONO_TYPE_TYPEDBYREF)) - { - /* The register is volatile */ - cfg->ret->opcode = OP_REGOFFSET; - cfg->ret->inst_basereg = cfg->frame_reg; - - /*if (cfg->arch.omit_fp) { - cfg->ret->inst_offset = offset; - offset += 8; - } else */ - { - cfg->ret->inst_offset = offset; - CFG_DEBUG(3) g_print ("ALPHA: Return offset is %x\n", offset); - offset += 8; - } - } - else - { - cfg->ret->opcode = OP_REGVAR; - cfg->ret->inst_c0 = cinfo->ret.reg; - } - break; - case ArgValuetypeInReg: - /* Allocate a local to hold the result, the epilog will - copy it to the correct place */ - // g_assert (!cfg->arch.omit_fp); - offset += 16; - cfg->ret->opcode = OP_REGOFFSET; - cfg->ret->inst_basereg = cfg->frame_reg; - cfg->ret->inst_offset = offset; - break; - default: - g_assert_not_reached (); - } - cfg->ret->dreg = cfg->ret->inst_c0; - } - - /* Allocate locals */ - offsets = mono_allocate_stack_slots (cfg, - /*cfg->arch.omit_fp ? FALSE:*/ TRUE, - &locals_stack_size, - &locals_stack_align); - - //g_assert((locals_stack_size % 8) == 0); - if (locals_stack_size % 8) - { - locals_stack_size += 8 - (locals_stack_size % 8); - } - - /* if (locals_stack_align) - { - offset += (locals_stack_align - 1); - offset &= ~(locals_stack_align - 1); - } - */ - - cfg->arch.localloc_offset = offset; - - CFG_DEBUG(3) g_print ("ALPHA: Locals start offset is %d(%x)\n", offset, offset); - CFG_DEBUG(3) g_print ("ALPHA: Locals size is %d(%x)\n", - locals_stack_size, locals_stack_size); - - for (i = cfg->locals_start; i < cfg->num_varinfo; i++) - { - if (offsets [i] != -1) { - MonoInst *inst = cfg->varinfo [i]; - inst->opcode = OP_REGOFFSET; - inst->inst_basereg = cfg->frame_reg; - //if (cfg->arch.omit_fp) - // inst->inst_offset = (offset + offsets [i]); - //else - inst->inst_offset = (offset + (locals_stack_size - offsets [i])); - - CFG_DEBUG(3) g_print ("ALPHA: allocated local %d to ", i); - CFG_DEBUG(3) mono_print_tree_nl (inst); - } - } - - // TODO check how offsets[i] are calculated - // it seems they are points to the end on data. Like 8, but it actually - 0 - - offset += locals_stack_size; //+8; - - if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG)) { - // g_assert (!cfg->arch.omit_fp); - g_assert (cinfo->sig_cookie.storage == ArgOnStack); - cfg->sig_cookie = cinfo->sig_cookie.offset + ARGS_OFFSET; - } - - // Save offset for caller saved regs - cfg->arch.reg_save_area_offset = offset; - - CFG_DEBUG(3) g_print ("ALPHA: reg_save_area_offset at %d(%x)\n", offset, offset); - - // Reserve space for caller saved registers - for (i = 0; i < MONO_MAX_IREGS; ++i) - if ((ALPHA_IS_CALLEE_SAVED_REG (i)) && - (cfg->used_int_regs & (1 << i))) - { - offset += sizeof (gpointer); - } - - // Save offset to args regs - cfg->arch.args_save_area_offset = offset; - - CFG_DEBUG(3) g_print ("ALPHA: args_save_area_offset at %d(%x)\n", offset, offset); - - for (i = 0; i < sig->param_count + sig->hasthis; ++i) - { - ArgInfo *ainfo = &cinfo->args [i]; - - switch(ainfo->storage) - { - case ArgInIReg: - case ArgInFloatReg: - case ArgInDoubleReg: - offset += sizeof (gpointer); - break; - case ArgAggregate: - offset += ainfo->nregs * sizeof (gpointer); - break; - default: - ; - } - } - - CFG_DEBUG(3) g_print ("ALPHA: Stack size is %d(%x)\n", - offset, offset); - - // Reserve space for method params - for (i = 0; i < sig->param_count + sig->hasthis; ++i) - { - inst = cfg->args [i]; - - if (inst->opcode != OP_REGVAR) - { - ArgInfo *ainfo = &cinfo->args [i]; - gboolean inreg = TRUE; - MonoType *arg_type; - - if (sig->hasthis && (i == 0)) - arg_type = &mono_defaults.object_class->byval_arg; - else - arg_type = sig->params [i - sig->hasthis]; - - /* FIXME: Allocate volatile arguments to registers */ - if (inst->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) - inreg = FALSE; - - /* - * Under AMD64, all registers used to pass arguments to functions - * are volatile across calls. For Alpha too. - * FIXME: Optimize this. - */ - - // Let's - if (inreg && (ainfo->storage == ArgInIReg) - //&& cfg->used_int_regs & (1 << ainfo->reg) - ) - inreg = FALSE; - - if (//(ainfo->storage == ArgInIReg) || - (ainfo->storage == ArgInFloatReg) || - (ainfo->storage == ArgInDoubleReg) || - (ainfo->storage == ArgValuetypeInReg)) - inreg = FALSE; - - inst->opcode = OP_REGOFFSET; - - switch (ainfo->storage) - { - case ArgInIReg: - case ArgInFloatReg: - case ArgInDoubleReg: - inst->opcode = OP_REGVAR; - inst->dreg = ainfo->reg; - break; - case ArgOnStack: - // g_assert (!cfg->arch.omit_fp); - inst->opcode = OP_REGOFFSET; - inst->inst_basereg = cfg->frame_reg; - - // "offset" here will point to the end of - // array of saved ret,locals, args - // Ideally it would point to "a7" - inst->inst_offset = ainfo->offset + offset; - break; - case ArgValuetypeInReg: - break; - case ArgAggregate: - inreg = FALSE; - break; - - default: - NOT_IMPLEMENTED; - } - - if (!inreg && (ainfo->storage != ArgOnStack)) - { - inst->opcode = OP_REGOFFSET; - inst->inst_basereg = cfg->frame_reg; - - /* These arguments are saved to the stack in the prolog */ - /*if (cfg->arch.omit_fp) { - inst->inst_offset = offset; - offset += (ainfo->storage == ArgValuetypeInReg) ? - 2 * sizeof (gpointer) : sizeof (gpointer); - } else */ - { - // offset += (ainfo->storage == ArgValuetypeInReg) ? - // 2 * sizeof (gpointer) : sizeof (gpointer); - - inst->inst_offset = cfg->arch.args_save_area_offset + a_off; - switch(ainfo->storage) - { - case ArgAggregate: - a_off += ainfo->nslots * 8; - break; - default: - a_off += sizeof (gpointer); - } - // (/*(ainfo->reg - 16)*/ i * 8); - } - } - } - } - - cfg->stack_offset = offset; - - g_free (cinfo); -} - -/*========================= End of Function ========================*/ - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_print_tree */ -/* */ -/* Function - Print platform-specific opcode details. */ -/* */ -/* Returns - 1 - opcode details have been printed */ -/* 0 - opcode details have not been printed */ -/* */ -/*------------------------------------------------------------------*/ - -gboolean -mono_arch_print_tree (MonoInst *tree, int arity) -{ - gboolean done; - - ALPHA_DEBUG("mono_arch_print_tree"); - - switch (tree->opcode) { - default: - done = 0; - } - return (done); -} - -/*========================= End of Function ========================*/ - -/* -** -** mono_arch_get_vcall_slot_addr -** is called by mono_magic_trampoline to determine that the JIT compiled -** method is called via vtable slot. We need to analyze call sequence -** and determine that. In case it is true - we need to return address -** of vtable slot. -** -** code - points to the next instruction after call -** reg - points to saved regs before the call (this is done -** by mono_magic_trampoline function -*/ - -gpointer* -mono_arch_get_vcall_slot_addr (guint8* code, mgreg_t *regs) -{ - unsigned int *pc = (unsigned int *)code; - guint32 reg, disp; - int start_index = -2; - - ALPHA_PRINT g_debug("ALPHA_CHECK: [mono_arch_get_vcall_slot_addr] code: %p regs: %p", - pc, regs); - - // Check if we have parameters on stack - if ((pc[-2] & 0xFFFF0000) == 0x23DE0000) // lda sp,-n(sp) - start_index = -3; - - // Check for (call_membase): - // -4: mov v0,a0 - load this ??? - // -3: ldq v0,0(v0) - load vtable - // -2: ldq t12,64(v0) - load method (object->vtable->vtable[method->slot]) - if ((pc[start_index-1] & 0xFC00FFFF) == 0xA4000000 && - (pc[start_index] & 0xFFFF0000) == 0xA7600000 - ) - { - disp = pc[start_index] & 0xFFFF; - reg = (pc[start_index-1] >> AXP_REG1_SHIFT) & AXP_REG_MASK; - //reg = 0; // For now - - ALPHA_PRINT g_debug("ALPHA_CHECK: [mono_arch_get_vcall_slot_addr callvirt] call_membase"); - - return (gpointer)(((guint64)(regs [reg])) + disp); - } - - // Check for interface call - // -5: mov v0,a0 - // -4: ldq v0,0(v0) - // -3: ldq v0,-n(v0) - // -2: ldq t12,0(v0) - if ((pc[start_index-2] & 0xFC00FFFF) == 0xA4000000 && - (pc[start_index-1] & 0xFFFF0000) == 0xA4000000 && - (pc[start_index] & 0xFFFF0000) == 0xA7600000 - ) - { - disp = pc[start_index] & 0xFFFF;; - reg = 0; // For now - - ALPHA_PRINT g_debug("ALPHA_CHECK: [mono_arch_get_vcall_slot_addr interf callvir] call_membase"); - - return (gpointer)(((guint64)(regs [reg])) + disp); - } - - return 0; -} - -gpointer -mono_arch_get_this_arg_from_call (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, mgreg_t *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; -} - -gpointer -mono_arch_context_get_int_reg (MonoContext *ctx, int reg) -{ - /* FIXME: implement */ - g_assert_not_reached (); -} diff --git a/mono/mini/mini-alpha.h b/mono/mini/mini-alpha.h deleted file mode 100644 index 40d6e4cec80..00000000000 --- a/mono/mini/mini-alpha.h +++ /dev/null @@ -1,308 +0,0 @@ -#ifndef __MONO_MINI_ALPHA_H__ -#define __MONO_MINI_ALPHA_H__ - -#include - -#include - -#define MONO_ARCH_CPU_SPEC alpha_desc - -/* Parameters used by the register allocator */ - -/* Max number of integer registers (all int regs). Required definition */ -#define MONO_MAX_IREGS 31 - -/* Max number of float registers (all float regs). Required definition */ -#define MONO_MAX_FREGS 32 - -typedef enum {GT_NONE, GT_INT, GT_LONG, - GT_PTR, GT_FLOAT, GT_DOUBLE, GT_LD_GTADDR} AlphaGotType; - -typedef struct -{ - union - { - int i; - long l; - void *p; - float f; - double d; - } data; -} AlphaGotData; - -typedef struct AlphaGotEntry -{ - struct AlphaGotEntry *next; - - AlphaGotType type; - AlphaGotData value; - - gpointer patch_info; - gpointer got_patch_info; -} AlphaGotEntry; - -typedef struct MonoCompileArch -{ - gint32 lmf_offset; - gint32 localloc_offset; - gint32 reg_save_area_offset; - gint32 args_save_area_offset; - gint32 stack_size; // Allocated stack size in bytes - gint32 params_stack_size; // Stack size reserved for call params by this compile method - - gpointer got_data; - glong bwx; -} MonoCompileArch; - -typedef struct ucontext MonoContext; - -struct MonoLMF -{ - gpointer previous_lmf; - gpointer lmf_addr; - MonoMethod *method; - guint64 ebp; // FP ? caller FP - 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 -#define MONO_ARCH_CODE_ALIGNMENT 8 - -// Regs available for allocation in compile unit -// For Alpha: r1-r14, r22-r25 -// 1111 1111 1111 1111 1111 1111 1111 1111 -// 098 7654 3210 9876 5432 1098 7654 3210 -// RRRR RRLL LLAA AAAA RLLL LLLL LLLL LLLL - No global regs -// RRRR RRLL LLAA AAAA RGGG LLLL LLLL LLLL - 3 global regs -//#define MONO_ARCH_CALLEE_REGS ((regmask_t)0x03C07FFF) -#define MONO_ARCH_CALLEE_REGS ((regmask_t)0x03C00FFF) -#define MONO_ARCH_CALLEE_FREGS ((regmask_t)0x03C07FFF) - -// These are the regs that are considered global -// and should not be used by JIT reg allocator -// (should be saved in compile unit). The JIT could use them -// in regalloc if they assigned as REGVARS (REGOFFSET to keep -// vars on stack -// the stack space will be reserved for them if they got used -// For Alpha - r9-r14. Actually later we could use some of the -// upper "t" regs, since local reg allocator doesn't like registers -// very much, so we could safely keep vars in them -//#define MONO_ARCH_CALLEE_SAVED_REGS ((regmask_t)0x3C00FE00) -#define MONO_ARCH_CALLEE_SAVED_REGS ((regmask_t)0x3C00F000) -#define MONO_ARCH_CALLEE_SAVED_FREGS 0 - -#define ALPHA_IS_CALLEE_SAVED_REG(reg) (MONO_ARCH_CALLEE_SAVED_REGS & (1 << (reg))) - -#define MONO_ARCH_USE_FPSTACK FALSE -#define MONO_ARCH_FPSTACK_SIZE 0 - -#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_pc)) -#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_regs[15])) -#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_regs[30])) - -#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->uc_mcontext.sc_pc = (long)(ip); } while (0); -#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->uc_mcontext.sc_regs[15] = (long)(bp); } while (0); -#define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->uc_mcontext.sc_regs[30] = (long)(esp); } while (0); - -#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do { \ - mono_arch_flush_register_windows (); \ - MONO_CONTEXT_SET_IP ((ctx), (start_func)); \ - MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0)); \ - MONO_CONTEXT_SET_SP ((ctx), __builtin_frame_address (0)); \ -} while (0) - -#define MONO_ARCH_USE_SIGACTION 1 - -//#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'r') ? IA64_R8 : ((desc == 'g') ? 8 : -1)) -//#define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g')) -#define MONO_ARCH_INST_SREG2_MASK(ins) (0) -#define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE -#define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1) - -// This define is called to get specific dest register as defined -// by md file (letter after "dest"). Overwise return -1 -//#define MONO_ARCH_INST_FIXED_REG(desc) (-1) -#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? alpha_at : ( (desc == 'a') ? alpha_r0 : -1) ) - -#if 0 - -/* r8..r11, r14..r29 */ -#define MONO_ARCH_CALLEE_REGS ((regmask_t)(0x700UL) | (regmask_t)(0x3fffc000UL)) - -/* f6..f15, f33..f127 */ -/* FIXME: Use the upper 64 bits as well */ -#define MONO_ARCH_CALLEE_FREGS ((regmask_t)(0xfffffffe00000000UL) | ((regmask_t)(0x3ffUL) << 6)) - -#define MONO_ARCH_CALLEE_SAVED_REGS ~(MONO_ARCH_CALLEE_REGS) - -#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 == 'r') ? IA64_R8 : ((desc == 'g') ? 8 : -1)) -#define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g')) -#define MONO_ARCH_INST_SREG2_MASK(ins) (0) -#define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE -#define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1) - -#define MONO_ARCH_IS_GLOBAL_IREG(reg) (is_hard_ireg (reg) && ((reg) >= cfg->arch.reg_local0) && ((reg) < cfg->arch.reg_out0)) - -#define MONO_ARCH_FRAME_ALIGNMENT 16 - -#define MONO_ARCH_CODE_ALIGNMENT 16 - -#define MONO_ARCH_RETREG1 IA64_R8 -#define MONO_ARCH_FRETREG1 8 - -#define MONO_ARCH_SIGNAL_STACK_SIZE SIGSTKSZ - -struct MonoLMF -{ - guint64 ebp; -}; - -typedef struct MonoContext { - unw_cursor_t cursor; -} MonoContext; - -typedef struct MonoCompileArch { - gint32 stack_alloc_size; - gint32 lmf_offset; - gint32 localloc_offset; - gint32 n_out_regs; - gint32 reg_in0; - gint32 reg_local0; - gint32 reg_out0; - gint32 reg_saved_ar_pfs; - gint32 reg_saved_b0; - gint32 reg_saved_sp; - gint32 reg_fp; - gint32 reg_saved_return_val; - guint32 prolog_end_offset, epilog_begin_offset, epilog_end_offset; - void *ret_var_addr_local; - unw_dyn_region_info_t *r_pro, *r_epilog; - void *last_bb; - Ia64CodegenState code; - gboolean omit_fp; - GHashTable *branch_targets; -} MonoCompileArch; - -static inline unw_word_t -mono_ia64_context_get_ip (MonoContext *ctx) -{ - unw_word_t ip; - int err; - - err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip); - g_assert (err == 0); - - /* Subtrack 1 so ip points into the actual instruction */ - return ip - 1; -} - -static inline unw_word_t -mono_ia64_context_get_sp (MonoContext *ctx) -{ - unw_word_t sp; - int err; - - err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp); - g_assert (err == 0); - - return sp; -} - -static inline unw_word_t -mono_ia64_context_get_fp (MonoContext *ctx) -{ - unw_cursor_t new_cursor; - unw_word_t fp; - int err; - - { - unw_word_t ip, sp; - - err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp); - g_assert (err == 0); - - err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip); - g_assert (err == 0); - } - - /* fp is the SP of the parent frame */ - new_cursor = ctx->cursor; - - err = unw_step (&new_cursor); - g_assert (err >= 0); - - err = unw_get_reg (&new_cursor, UNW_IA64_SP, &fp); - g_assert (err == 0); - - return fp; -} - -#define MONO_CONTEXT_SET_IP(ctx,eip) do { int err = unw_set_reg (&(ctx)->cursor, UNW_IA64_IP, (unw_word_t)(eip)); g_assert (err == 0); } while (0) -#define MONO_CONTEXT_SET_BP(ctx,ebp) do { } while (0) -#define MONO_CONTEXT_SET_SP(ctx,esp) do { int err = unw_set_reg (&(ctx)->cursor, UNW_IA64_SP, (unw_word_t)(esp)); g_assert (err == 0); } while (0) - -#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)(mono_ia64_context_get_ip ((ctx)))) -#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)(mono_ia64_context_get_fp ((ctx)))) -#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)(mono_ia64_context_get_sp ((ctx)))) - -#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do { \ - MONO_INIT_CONTEXT_FROM_CURRENT (ctx); \ -} while (0) - -#define MONO_INIT_CONTEXT_FROM_CURRENT(ctx) do { \ - int res; \ - res = unw_getcontext (&unw_ctx); \ - g_assert (res == 0); \ - res = unw_init_local (&(ctx)->cursor, &unw_ctx); \ - g_assert (res == 0); \ -} while (0) - -#define MONO_ARCH_CONTEXT_DEF unw_context_t unw_ctx; - -#define MONO_ARCH_USE_SIGACTION 1 - -#ifdef HAVE_WORKING_SIGALTSTACK -/*#define MONO_ARCH_SIGSEGV_ON_ALTSTACK*/ -#endif - -unw_dyn_region_info_t* mono_ia64_create_unwind_region (Ia64CodegenState *code); - -#define MONO_ARCH_NO_EMULATE_MUL_IMM 1 - -#define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1 - -#define MONO_ARCH_HAVE_INVALIDATE_METHOD 1 -#define MONO_ARCH_HAVE_SAVE_UNWIND_INFO 1 - -#endif - -#define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1 - -#define MONO_ARCH_EMULATE_CONV_R8_UN 1 -#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1 -//#define MONO_ARCH_EMULATE_LCONV_TO_R8 1 -#define MONO_ARCH_EMULATE_FREM 1 -#define MONO_ARCH_EMULATE_MUL_DIV 1 -#define MONO_ARCH_EMULATE_LONG_MUL_OPTS 1 -#define MONO_ARCH_NEED_DIV_CHECK 1 - - -#define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1 - -typedef struct { - guint8 *address; - guint8 *saved_byte; -} MonoBreakpointInfo; - -extern MonoBreakpointInfo mono_breakpoint_info[MONO_BREAKPOINT_ARRAY_SIZE]; -#endif /* __MONO_MINI_ALPHA_H__ */ diff --git a/mono/mini/mini-arch.h b/mono/mini/mini-arch.h index 23d890dd89d..d47bcb18a73 100644 --- a/mono/mini/mini-arch.h +++ b/mono/mini/mini-arch.h @@ -19,8 +19,6 @@ #include "mini-ia64.h" #elif defined(TARGET_ARM) #include "mini-arm.h" -#elif defined(__alpha__) -#include "mini-alpha.h" #elif defined(__mips__) #include "mini-mips.h" #else diff --git a/mono/mini/mini-ops.h b/mono/mini/mini-ops.h index 1641e62ca65..5cd41e6ff56 100644 --- a/mono/mini/mini-ops.h +++ b/mono/mini/mini-ops.h @@ -1151,30 +1151,6 @@ MINI_OP(OP_IA64_LOADR4_MEMBASE_INC,"ia64_loadr4_membase_inc", IREG, IREG, NONE) MINI_OP(OP_IA64_LOADR8_MEMBASE_INC,"ia64_loadr8_membase_inc", IREG, IREG, NONE) #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") -MINI_OP(OP_ALPHA_CMPT_EQ_SU, "alpha_cmpt_eq_su") -MINI_OP(OP_ALPHA_CMPT_LT, "alpha_cmpt_lt") -MINI_OP(OP_ALPHA_CMPT_LT_SU, "alpha_cmpt_lt_su") -MINI_OP(OP_ALPHA_CMPT_LE, "alpha_cmpt_le") -MINI_OP(OP_ALPHA_CMPT_LE_SU, "alpha_cmpt_le_su") -MINI_OP(OP_ALPHA_CMPT_UN, "alpha_cmpt_un") -MINI_OP(OP_ALPHA_CMPT_UN_SU, "alpha_cmpt_un_su") -MINI_OP(OP_ALPHA_TRAPB, "alpha_trapb") - -#endif - #if defined(__mips__) MINI_OP(OP_MIPS_BEQ, "mips_beq", NONE, IREG, IREG) MINI_OP(OP_MIPS_BGEZ, "mips_bgez", NONE, IREG, NONE) diff --git a/mono/mini/tramp-alpha.c b/mono/mini/tramp-alpha.c deleted file mode 100644 index cab03d65ec5..00000000000 --- a/mono/mini/tramp-alpha.c +++ /dev/null @@ -1,632 +0,0 @@ -/*------------------------------------------------------------------*/ -/* */ -/* Name - tramp-alpha.c */ -/* */ -/* Function - JIT trampoline code for Alpha. */ -/* */ -/* Name - Sergey Tikhonov (tsv@solvo.ru) */ -/* */ -/* Date - January, 2006 */ -/* */ -/* Derivation - From exceptions-amd64 & exceptions-ia64 */ -/* Dietmar Maurer (dietmar@ximian.com) */ -/* Zoltan Varga (vargaz@gmail.com) */ -/* */ -/* */ -/*------------------------------------------------------------------*/ - -/*------------------------------------------------------------------*/ -/* D e f i n e s */ -/*------------------------------------------------------------------*/ -#define ALPHA_DEBUG(x) \ - if (mini_alpha_verbose_level) \ - g_debug ("ALPHA_DEBUG: %s is called.", x); - -#define ALPHA_PRINT if (mini_alpha_verbose_level) - -/*========================= End of Defines =========================*/ - -/*------------------------------------------------------------------*/ -/* I n c l u d e s */ -/*------------------------------------------------------------------*/ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "mini.h" -#include "mini-alpha.h" - -/*========================= End of Includes ========================*/ - -/*------------------------------------------------------------------*/ -/* T y p e d e f s */ -/*------------------------------------------------------------------*/ - -/*========================= End of Typedefs ========================*/ - -/*------------------------------------------------------------------*/ -/* P r o t o t y p e s */ -/*------------------------------------------------------------------*/ - -/*========================= End of Prototypes ======================*/ - -/*------------------------------------------------------------------*/ -/* G l o b a l V a r i a b l e s */ -/*------------------------------------------------------------------*/ - - -/*====================== End of Global Variables ===================*/ - -extern int mini_alpha_verbose_level; - -/*------------------------------------------------------------------*/ -/* */ -/* Name - mono_arch_create_trampoline_code */ -/* */ -/* Function - Create the designated type of trampoline according*/ -/* to the 'tramp_type' parameter. */ -/* */ -/* - This code should expect to be called by tramp stub function - On Alpha: - - pv points to start of stub function - - at points to start of this trampoline - - allocate stack to save all regs and lmfs - - save regs - - save lmf - - fill params for trampoline methods (They expect 4 params) - - call trampoline method (by standard call convention (pv + ra)) - - save return value (r0) - - restore saved regs + lmfs - - restore stack (don't forget space allocated by stub) - - use saved return values as new address to give control to - - return or jump to new address (don't expect to return here - - don't save return address. RA will be holding return address - of original caller of tramp stub function). New address function - expect standart calling convention (pv) - -*/ -/*------------------------------------------------------------------*/ - -guchar * -mono_arch_create_trampoline_code (MonoTrampolineType tramp_type) -{ - unsigned int *buf, *code, *tramp; - int i, offset, framesize, off, lmf_offset, saved_regs_offset; - //int saved_fpregs_offset, saved_regs_offset, method_offset, tramp_offset; - - gboolean has_caller; - - ALPHA_DEBUG("mono_arch_create_trampoline_code"); - - if (tramp_type == MONO_TRAMPOLINE_JUMP) - has_caller = FALSE; - else - has_caller = TRUE; - - code = buf = mono_global_codeman_reserve (1024); - - framesize = 1024 + sizeof (MonoLMF); - framesize = (framesize + - (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~(MONO_ARCH_FRAME_ALIGNMENT - 1); - - offset = 16; - - // Expect that generated code is called with 2 parameters - // method and tramp (in a0 and a1) - - // Allocate stack - alpha_lda(code, alpha_sp, alpha_sp, -framesize); - - /* store call convention parameters on stack.*/ - alpha_stq( code, alpha_ra, alpha_sp, 0 ); // ra - alpha_stq( code, alpha_fp, alpha_sp, 8 ); // fp - - saved_regs_offset = offset; - - // Store all integer regs - for (i=0; i<30 /*alpha_pc*/; i++) - { - alpha_stq(code, i, alpha_sp, offset); - offset += 8; - } - - // Store all fp regs - for (i=0; i> 32) & 0xFFFFFFFF); - code++; - - /* - * The call might clobber argument registers, but they are already - * saved to the stack/global regs. - */ - alpha_jsr(code, alpha_ra, alpha_pv, 0); - - // Save lmf_addr - alpha_stq(code, alpha_r0, alpha_sp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, lmf_addr))); - // Load "previous_lmf" member of MonoLMF struct - alpha_ldq(code, alpha_r1, alpha_r0, 0); - - // Save it to MonoLMF struct - alpha_stq(code, alpha_r1, alpha_sp, - (lmf_offset + G_STRUCT_OFFSET(MonoLMF, previous_lmf))); - // Set new LMF - alpha_lda(code, alpha_r1, alpha_sp, lmf_offset); - alpha_stq(code, alpha_r1, alpha_r0, 0); - } - - - /* set the frame pointer */ - alpha_mov1( code, alpha_sp, alpha_fp ); - - /* Arg3 is the method/vtable ptr */ - alpha_ldq(code, alpha_a2, alpha_sp, framesize); - //alpha_mov1(code, alpha_a0, alpha_a2); - - /* Arg4 is the trampoline address */ - // Load PV from saved regs - later optimize it and load into a3 directly - alpha_ldq(code, alpha_pv, alpha_sp, (saved_regs_offset + (alpha_pv*8))); - alpha_mov1(code, alpha_pv, alpha_a3); - //alpha_mov1(code, alpha_a1, alpha_a3); - - /* Arg1 is the pointer to the saved registers */ - alpha_lda(code, alpha_a0, alpha_sp, 16); - - alpha_ldq(code, alpha_ra, alpha_sp, (saved_regs_offset + (alpha_ra*8))); - /* Arg2 is the address of the calling code */ - if (has_caller) - alpha_mov1(code, alpha_ra, alpha_a1); - else - alpha_mov1(code, alpha_zero, alpha_a1); - - /* Arg3 is the method/vtable ptr - alpha_mov1(code, alpha_a0, alpha_a2); - - Arg4 is the trampoline address - alpha_mov1(code, alpha_a1, alpha_a3); - */ - - if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT) - tramp = (unsigned int*)mono_class_init_trampoline; - else if (tramp_type == MONO_TRAMPOLINE_AOT) - tramp = (unsigned int*)mono_aot_trampoline; - else if (tramp_type == MONO_TRAMPOLINE_DELEGATE) - tramp = (unsigned int*)mono_delegate_trampoline; - else - tramp = (unsigned int*)mono_magic_trampoline; - - // Restore AT - alpha_ldq(code, alpha_at, alpha_sp, (saved_regs_offset + (alpha_at*8))); - - off = (char *)code - (char *)buf; - off += 2*4; - - if (off % 8) - { - alpha_nop(code); - off += 4; - } - - // alpha_at points to start of this method !!! - alpha_ldq(code, alpha_pv, alpha_at, off); - alpha_br(code, alpha_zero, 2); - - *code = (unsigned int)(((unsigned long)tramp) & 0xFFFFFFFF); - code++; - *code = (unsigned int)((((unsigned long)tramp) >> 32) & 0xFFFFFFFF); - code++; - - alpha_jsr(code, alpha_ra, alpha_pv, 0); - - alpha_stq(code, alpha_r0, alpha_sp, framesize); - - /* Restore LMF */ - if (1) - { - /* Restore previous lmf */ - alpha_ldq(code, alpha_at, alpha_sp, - (lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf))); - alpha_ldq(code, alpha_ra, alpha_sp, - (lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr))); - alpha_stq(code, alpha_at, alpha_ra, 0); - } - - offset = 16; - - // Restore all integer regs - for (i=0; i<30 /*alpha_pc*/; i++) - { - alpha_ldq(code, i, alpha_sp, offset); - offset += 8; - } - - // Restore all float regs - for (i=0; i> 32) & 0xFFFFFFFF); - code++; - - // Store arg1 on stack - alpha_stq(code, alpha_at, alpha_sp, 0); - - offset = (char *)code - (char *)buf; - offset += 2*4; - if (offset % 8) - { - alpha_nop(code); - offset += 4; - } - - alpha_ldq(code, alpha_at, alpha_pv, offset); - alpha_br(code, alpha_zero, 2); - - *code = (unsigned int)(((unsigned long)tramp) & 0xFFFFFFFF); - code++; - *code = (unsigned int)((((unsigned long)tramp) >> 32) & 0xFFFFFFFF); - code++; - - // Jump to trampoline - alpha_jmp(code, alpha_zero, alpha_at, 0); - - g_assert (((char *)code - (char *)buf) <= TRAMPOLINE_SIZE); - /* - * FIXME: Changing the size to code - buf causes strange crashes during - * mcs bootstrap. - */ - real_code = mono_domain_code_reserve (domain, TRAMPOLINE_SIZE); - size = (char *)code - (char *)buf; - - memcpy (real_code, buf, size); - - ALPHA_PRINT - g_debug("mono_arch_create_specific_trampoline: Target: %p, Arg1: %p", - real_code, arg1); - - if (code_len) - *code_len = size; - - mono_arch_flush_icache ((guchar *)real_code, size); - - return real_code; -} -/*========================= End of Function ========================*/ - -void -mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs) -{ - unsigned int *pcode = (unsigned int *)code; - - ALPHA_DEBUG("mono_arch_nullify_class_init_trampoline"); - - // pcode[-2] ldq t12,n(gp) - // pcode[-1] jsr ra,(t12),0x20003efcb40 - if ((pcode[-2] & 0xFFFF0000) == 0xa77d0000 && - pcode[-1] == 0x6b5b4000) - { - // Put "unop" into call inst - pcode--; - alpha_nop(pcode); - alpha_nop(pcode); - alpha_nop(pcode); - - mono_arch_flush_icache ((code-4), 3*4); - } - else - g_assert_not_reached (); -} - -void -mono_arch_patch_callsite (guint8 *method_start, guint8 *code, guint8 *addr) -{ - unsigned long *p = (unsigned int *)(code-12); - - unsigned int *pcode = (unsigned int *)code; - unsigned long gp = (unsigned long)pcode; - unsigned int call_addr_inst; - short high_offset, low_offset; - - ALPHA_DEBUG("mono_arch_patch_callsite"); - - // Code points to the next instruction after the "jsr" - // In current implementation where we put jump addresses - // inside the code - we need to put "new" address into - // "code-12" - - // With new method of using GOT we need to find address - // where function address is stored - // code points to two insts: - // ldah gp, high_offset(ra) - // lda gp, low_offset(gp) - // - - high_offset = *((short *)pcode); - low_offset = *((short *)(pcode + 1)); - - gp += 65536 * high_offset + low_offset; - - call_addr_inst = *(pcode - 2); - - // Check for load address instruction - // It should be ldq t12, offset(gp) - if ((call_addr_inst & 0xFFFF0000) == 0xA77D0000) - { - gp += *((short *)(pcode - 2)); - - p = (unsigned long *)gp; - - ALPHA_PRINT g_debug("Patch callsite at %p to %p\n", p, addr); - - // TODO - need to to interlocked update here - *p = (unsigned long)addr; - } -} - -/* - * mono_arch_get_unbox_trampoline: - * @gsctx: the generic sharing context - * @m: method pointer - * @addr: pointer to native code for @m - * - * when value type methods are called through the vtable we need to unbox the - * this argument. This method returns a pointer to a trampoline which does - * unboxing before calling the method - */ -gpointer -mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *m, gpointer addr) -{ - unsigned int *code, *start_code; - int this_reg = 16; //R16 - int off; - MonoDomain *domain = mono_domain_get (); - - ALPHA_DEBUG("mono_arch_get_unbox_trampoline"); - - if (MONO_TYPE_ISSTRUCT (mono_method_signature (m)->ret)) - this_reg = 17; //R17 - - start_code = code = (unsigned int *)mono_domain_code_reserve (domain, 32); - - // Adjust this by size of MonoObject - alpha_addq_(code, this_reg, sizeof(MonoObject), this_reg); // 0 - alpha_bsr(code, alpha_pv, 2); // 4 - - *code = (unsigned int)(((unsigned long)addr) & 0xFFFFFFFF); - code++; - *code = (unsigned int)((((unsigned long)addr) >> 32) & 0xFFFFFFFF); - code++; - - // Load "addr" into PV (R12) - alpha_ldq(code, alpha_pv, alpha_pv, 0); - - // Jump to addr - alpha_jsr(code, alpha_zero, alpha_pv, 0); - - g_assert (((char *)code - (char *)start_code) < 32); - - mono_arch_flush_icache (start_code, (char *)code - (char *)start_code); - - return start_code; -} - -void -mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs) -{ - g_assert_not_reached (); -} - -void -mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr) -{ - g_assert_not_reached (); -} - -gpointer -mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 encoded_offset) -{ - /* FIXME: implement! */ - g_assert_not_reached (); - return NULL; -} diff --git a/mono/utils/mono-membar.h b/mono/utils/mono-membar.h index 80dfd2f5995..dd37c80660f 100644 --- a/mono/utils/mono-membar.h +++ b/mono/utils/mono-membar.h @@ -160,21 +160,6 @@ static inline void mono_memory_write_barrier (void) { mono_memory_barrier (); } -#elif defined(__alpha__) -static inline void mono_memory_barrier (void) -{ - __asm__ __volatile__ ("mb" : : : "memory"); -} - -static inline void mono_memory_read_barrier (void) -{ - mono_memory_barrier (); -} - -static inline void mono_memory_write_barrier (void) -{ - mono_memory_barrier (); -} #elif defined(__mips__) static inline void mono_memory_barrier (void) { -- 2.25.1