[arm64] Add JIT support.
authorZoltan Varga <vargaz@gmail.com>
Sat, 19 Apr 2014 18:16:47 +0000 (20:16 +0200)
committerZoltan Varga <vargaz@gmail.com>
Tue, 22 Apr 2014 17:34:26 +0000 (19:34 +0200)
15 files changed:
mono/arch/arm64/arm64-codegen.h [new file with mode: 0644]
mono/mini/Makefile.am.in
mono/mini/cpu-arm64.md [new file with mode: 0644]
mono/mini/exceptions-arm64.c [new file with mode: 0644]
mono/mini/genmdesc.pl
mono/mini/helpers.c
mono/mini/method-to-ir.c
mono/mini/mini-arch.h
mono/mini/mini-arm64.c [new file with mode: 0644]
mono/mini/mini-arm64.h [new file with mode: 0644]
mono/mini/mini-codegen.c
mono/mini/mini-gc.c
mono/mini/mini-ops.h
mono/mini/tramp-arm64.c [new file with mode: 0644]
mono/mini/unwind.c

diff --git a/mono/arch/arm64/arm64-codegen.h b/mono/arch/arm64/arm64-codegen.h
new file mode 100644 (file)
index 0000000..259ff96
--- /dev/null
@@ -0,0 +1,3 @@
+#include "../../../../mono-extensions/mono/arch/arm64/arm64-codegen.h"
+
+
index 55e5f14abf26e2204fb82ac5bb7f6c75f676d07a..cd935b50bb78fd589bc654a90f2819d07b3d3fec 100755 (executable)
@@ -317,6 +317,12 @@ arm_sources = \
        exceptions-arm.c        \
        tramp-arm.c
 
+arm64_sources = \
+       mini-arm64.c            \
+       mini-arm64.h            \
+       exceptions-arm64.c      \
+       tramp-arm64.c
+
 mips_sources = \
        mini-mips.c             \
        mini-mips.h             \
@@ -486,6 +492,12 @@ arch_built=cpu-arm.h
 arch_define=__arm__
 endif
 
+if ARM64
+arch_sources = $(arm64_sources)
+arch_built=cpu-arm64.h
+arch_define=__aarch64__
+endif
+
 if SPARC
 arch_sources = $(sparc_sources)
 arch_built=cpu-sparc.h
@@ -614,6 +626,9 @@ cpu-ppc64.h: cpu-ppc64.md genmdesc$(EXEEXT)
 cpu-arm.h: cpu-arm.md genmdesc$(EXEEXT)
        $(GENMDESC_PRG) cpu-arm.h arm_cpu_desc $(srcdir)/cpu-arm.md
 
+cpu-arm64.h: cpu-arm64.md genmdesc$(EXEEXT)
+       $(GENMDESC_PRG) cpu-arm64.h arm64_cpu_desc $(srcdir)/cpu-arm64.md
+
 cpu-sparc.h: cpu-sparc.md genmdesc$(EXEEXT)
        $(GENMDESC_PRG) cpu-sparc.h sparc_desc $(srcdir)/cpu-sparc.md
 
@@ -718,6 +733,7 @@ EXTRA_DIST = TestDriver.cs ldscript ldscript.mono \
        $(amd64_sources) cpu-amd64.md           \
        $(ppc_sources) cpu-ppc.md cpu-ppc64.md  \
        $(arm_sources) cpu-arm.md               \
+       $(arm64_sources) cpu-arm64.md           \
        $(mips_sources) cpu-mips.md             \
        $(sparc_sources) cpu-sparc.md           \
        $(s390x_sources) cpu-s390x.md           \
diff --git a/mono/mini/cpu-arm64.md b/mono/mini/cpu-arm64.md
new file mode 100644 (file)
index 0000000..d57b6ee
--- /dev/null
@@ -0,0 +1,424 @@
+# Copyright 2011-2013 Xamarin, Inc (http://www.xamarin.com)
+# Copyright 2003-2011 Novell, Inc (http://www.novell.com)
+# arm64 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
+#
+# register may have the following values:
+#      i  integer register
+#      a  r3 register (output from calls)
+#      b  base register (used in address references)
+#      f  floating point register
+#      g  floating point register returned in r0:r1 for soft-float mode
+#
+# len:number         describe the maximun length in bytes of the instruction
+# number is a positive integer
+#
+# 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
+#
+# spec can be one of the following characters:
+#      c  clobbers caller-save registers
+#      r  'reserves' the destination register until a later instruction unreserves it
+#          used mostly to set output registers in function calls
+#
+# flags:spec        describe if the instruction uses or sets the flags (unused)
+#
+# spec can be one of the following chars:
+#      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.
+#
+memory_barrier: len:8 clob:a
+nop: len:4
+relaxed_nop: len:4
+break: len:20
+jmp: len:92
+br: len:16
+switch: src1:i len:12
+# See the comment in resume_from_signal_handler, we can't copy the fp regs from sigctx to MonoContext on linux,
+# since the corresponding sigctx structures are not well defined.
+seq_point: len:38 clob:c
+
+throw: src1:i len:24
+rethrow: src1:i len:20
+start_handler: len:32
+endfinally: len:32
+call_handler: len:16 clob:c
+endfilter: src1:i len:32
+
+ckfinite: dest:f src1:f len:64
+ceq: dest:i len:12
+cgt: dest:i len:12
+cgt.un: dest:i len:12
+clt: dest:i len:12
+clt.un: dest:i len:12
+localloc: dest:i src1:i len:96
+compare: src1:i src2:i len:4
+compare_imm: src1:i len:20
+fcompare: src1:f src2:f len:12
+oparglist: src1:i len:12
+setlret: src1:i src2:i len:12
+checkthis: src1:b len:4
+call: dest:a clob:c len:32
+call_reg: dest:a src1:i len:32 clob:c
+call_membase: dest:a src1:b len:32 clob:c
+voidcall: len:32 clob:c
+voidcall_reg: src1:i len:32 clob:c
+voidcall_membase: src1:b len:32 clob:c
+fcall: dest:f len:32 clob:c
+fcall_reg: dest:f src1:i len:32 clob:c
+fcall_membase: dest:f src1:b len:32 clob:c
+lcall: dest:l len:32 clob:c
+lcall_reg: dest:l src1:i len:32 clob:c
+lcall_membase: dest:l src1:b len:32 clob:c
+vcall: len:32 clob:c
+vcall_reg: src1:i len:32 clob:c
+vcall_membase: src1:b len:32 clob:c
+tailcall: len:64
+iconst: dest:i len:16
+r4const: dest:f len:24
+r8const: dest:f len:20
+label: len:0
+store_membase_imm: dest:b len:20
+store_membase_reg: dest:b src1:i len:20
+storei1_membase_imm: dest:b len:20
+storei1_membase_reg: dest:b src1:i len:12
+storei2_membase_imm: dest:b len:20
+storei2_membase_reg: dest:b src1:i len:12
+storei4_membase_imm: dest:b len:20
+storei4_membase_reg: dest:b src1:i len:20
+storer4_membase_reg: dest:b src1:f len:20
+storer8_membase_reg: dest:b src1:f len:24
+store_memindex: dest:b src1:i src2:i len:4
+storei1_memindex: dest:b src1:i src2:i len:4
+storei2_memindex: dest:b src1:i src2:i len:4
+storei4_memindex: dest:b src1:i src2:i len:4
+load_membase: dest:i src1:b len:20
+loadi1_membase: dest:i src1:b len:32
+loadu1_membase: dest:i src1:b len:32
+loadi2_membase: dest:i src1:b len:32
+loadu2_membase: dest:i src1:b len:32
+loadi4_membase: dest:i src1:b len:32
+loadu4_membase: dest:i src1:b len:32
+loadr4_membase: dest:f src1:b len:32
+loadr8_membase: dest:f src1:b len:32
+load_memindex: dest:i src1:b src2:i len:4
+loadi1_memindex: dest:i src1:b src2:i len:4
+loadu1_memindex: dest:i src1:b src2:i len:4
+loadi2_memindex: dest:i src1:b src2:i len:4
+loadu2_memindex: dest:i src1:b src2:i len:4
+loadi4_memindex: dest:i src1:b src2:i len:4
+loadu4_memindex: dest:i src1:b src2:i len:4
+loadu4_mem: dest:i len:8
+move: dest:i src1:i len:4
+fmove: dest:f src1:f len:4
+add_imm: dest:i src1:i len:12
+sub_imm: dest:i src1:i len:12
+mul_imm: dest:i src1:i len:12
+and_imm: dest:i src1:i len:12
+or_imm: dest:i src1:i len:12
+xor_imm: dest:i src1:i len:12
+shl_imm: dest:i src1:i len:8
+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:8
+cond_exc_gt_un: len:8
+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:12
+cond_exc_no: len:8
+cond_exc_c: len:12
+cond_exc_nc: len:8
+#float_beq: src1:f src2:f len:20
+#float_bne_un: src1:f src2:f len:20
+#float_blt: src1:f src2:f len:20
+#float_blt_un: src1:f src2:f len:20
+#float_bgt: src1:f src2:f len:20
+#float_bgt_un: src1:f src2:f len:20
+#float_bge: src1:f src2:f len:20
+#float_bge_un: src1:f src2:f len:20
+#float_ble: src1:f src2:f len:20
+#float_ble_un: src1:f src2:f len:20
+float_add: dest:f src1:f src2:f len:4
+float_sub: dest:f src1:f src2:f len:4
+float_mul: dest:f src1:f src2:f len:4
+float_div: dest:f src1:f src2:f len:4
+float_div_un: dest:f src1:f src2:f len:4
+float_rem: dest:f src1:f src2:f len:16
+float_rem_un: dest:f src1:f src2:f len:16
+float_neg: dest:f src1:f len:4
+float_not: dest:f src1:f len:4
+float_conv_to_i1: dest:i src1:f len:40
+float_conv_to_i2: dest:i src1:f len:40
+float_conv_to_i4: dest:i src1:f len:40
+float_conv_to_i8: dest:l src1:f len:40
+float_conv_to_r4: dest:f src1:f len:8
+float_conv_to_u4: dest:i src1:f len:40
+float_conv_to_u8: dest:l src1:f len:40
+float_conv_to_u2: dest:i src1:f len:40
+float_conv_to_u1: dest:i src1:f len:40
+float_conv_to_i: dest:i src1:f len:40
+float_ceq: dest:i src1:f src2:f len:16
+float_cgt: dest:i src1:f src2:f len:16
+float_cgt_un: dest:i src1:f src2:f len:20
+float_clt: dest:i src1:f src2:f len:16
+float_clt_un: dest:i src1:f src2:f len:20
+float_cneq: dest:i src1:f src2:f len:20
+float_cge: dest:i src1:f src2:f len:20
+float_cle: dest:i src1:f src2:f len:20
+float_conv_to_u: dest:i src1:f len:36
+setfret: src1:f len:12
+aot_const: dest:i len:16
+objc_get_selector: dest:i len:32
+sqrt: dest:f src1:f len:4
+adc: dest:i src1:i src2:i len:4
+addcc: dest:i src1:i src2:i len:4
+subcc: dest:i src1:i src2:i len:4
+adc_imm: dest:i src1:i len:12
+addcc_imm: dest:i src1:i len:12
+subcc_imm: dest:i src1:i len:12
+sbb: dest:i src1:i src2:i len:4
+sbb_imm: dest:i src1:i len:12
+br_reg: src1:i len:8
+bigmul: len:8 dest:l src1:i src2:i
+bigmul_un: len:8 dest:l src1:i src2:i
+tls_get: dest:i len:32
+tls_get_reg: dest:i src1:i len:32
+tls_set: src1:i len:32
+tls_set_reg: src1:i src2:i len:32
+
+# 32 bit opcodes
+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 len:4
+int_div: dest:i src1:i src2:i len:72
+int_div_un: dest:i src1:i src2:i len:72
+int_rem: dest:i src1:i src2:i len:72
+int_rem_un: dest:i src1:i src2:i len:72
+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:4
+int_shr: dest:i src1:i src2:i len:4
+int_shr_un: dest:i src1:i src2:i len:4
+int_neg: dest:i src1:i len:4
+int_not: dest:i src1:i len:4
+int_conv_to_i1: dest:i src1:i len:8
+int_conv_to_i2: dest:i src1:i len:8
+int_conv_to_i4: dest:i src1:i len:4
+int_conv_to_r4: dest:f src1:i len:36
+int_conv_to_r8: dest:f src1:i len:36
+int_conv_to_u4: dest:i src1:i
+int_conv_to_r_un: dest:f src1:i len:56
+int_conv_to_u2: dest:i src1:i len:8
+int_conv_to_u1: dest:i src1:i len:4
+int_beq: len:16
+int_bge: len:16
+int_bgt: len:16
+int_ble: len:16
+int_blt: len:16
+int_bne_un: len:16
+int_bge_un: len:16
+int_bgt_un: len:16
+int_ble_un: len:16
+int_blt_un: len:16
+int_add_ovf: dest:i src1:i src2:i len:16
+int_add_ovf_un: dest:i src1:i src2:i len:16
+int_mul_ovf: dest:i src1:i src2:i len:16
+int_mul_ovf_un: dest:i src1:i src2:i len:16
+int_sub_ovf: dest:i src1:i src2:i len:16
+int_sub_ovf_un: dest:i src1:i src2:i len:16
+add_ovf_carry: dest:i src1:i src2:i len:16
+sub_ovf_carry: dest:i src1:i src2:i len:16
+add_ovf_un_carry: dest:i src1:i src2:i len:16
+sub_ovf_un_carry: dest:i src1:i src2:i len:16
+
+arm_rsbs_imm: dest:i src1:i len:4
+arm_rsc_imm: dest:i src1:i len:4
+
+# Linear IR opcodes
+dummy_use: src1:i len:0
+dummy_store: len:0
+not_reached: len:0
+not_null: src1:i len:0
+
+int_adc: dest:i src1:i src2:i len:4
+int_addcc: dest:i src1:i src2:i len:4
+int_subcc: dest:i src1:i src2:i len:4
+int_sbb: dest:i src1:i src2:i len:4
+int_adc_imm: dest:i src1:i len:12
+int_sbb_imm: dest:i src1:i len:12
+
+int_add_imm: dest:i src1:i len:12
+int_sub_imm: dest:i src1:i len:12
+int_mul_imm: dest:i src1:i len:12
+int_div_imm: dest:i src1:i len:20
+int_div_un_imm: dest:i src1:i len:12
+int_rem_imm: dest:i src1:i len:28
+int_rem_un_imm: dest:i src1:i len:16
+int_and_imm: dest:i src1:i len:12
+int_or_imm: dest:i src1:i len:12
+int_xor_imm: dest:i src1:i len:12
+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_ceq: dest:i len:12
+int_cgt: dest:i len:12
+int_cgt_un: dest:i len:12
+int_clt: dest:i len:12
+int_clt_un: dest:i len:12
+
+int_cneq: dest:i len:12
+int_cge: dest:i len:12
+int_cle: dest:i len:12
+int_cge_un: dest:i len:12
+int_cle_un: dest:i len:12
+
+cond_exc_ieq: len:16
+cond_exc_ine_un: len:16
+cond_exc_ilt: len:16
+cond_exc_ilt_un: len:16
+cond_exc_igt: len:16
+cond_exc_igt_un: len:16
+cond_exc_ige: len:16
+cond_exc_ige_un: len:16
+cond_exc_ile: len:16
+cond_exc_ile_un: len:16
+cond_exc_iov: len:20
+cond_exc_ino: len:16
+cond_exc_ic: len:20
+cond_exc_inc: len:16
+
+icompare: src1:i src2:i len:4
+icompare_imm: src1:i len:12
+
+long_conv_to_ovf_i4_2: dest:i src1:i src2:i len:36
+
+vcall2: len:32 clob:c
+vcall2_reg: src1:i len:32 clob:c
+vcall2_membase: src1:b len:32 clob:c
+dyn_call: src1:i src2:i len:120 clob:c
+
+# This is different from the original JIT opcodes
+float_beq: len:32
+float_bne_un: len:32
+float_blt: len:32
+float_blt_un: len:32
+float_bgt: len:32
+float_bgt_un: len:32
+float_bge: len:32
+float_bge_un: len:32
+float_ble: len:32
+float_ble_un: len:32
+
+liverange_start: len:0
+liverange_end: len:0
+gc_liveness_def: len:0
+gc_liveness_use: len:0
+gc_spill_slot_liveness_def: len:0
+gc_param_slot_liveness_def: len:0
+
+# 64 bit opcodes
+i8const: dest:i len:16
+sext_i4: dest:i src1:i len:4
+zext_i4: dest:i src1:i len:4
+jump_table: dest:i len:16
+long_add: dest:i src1:i src2:i len:4
+long_sub: dest:i src1:i src2:i len:4
+long_mul: dest:i src1:i src2:i len:4
+long_div: dest:i src1:i src2:i len:80
+long_div_un: dest:i src1:i src2:i len:64
+long_rem: dest:i src1:i src2:i len:80
+long_rem_un: dest:i src1:i src2:i len:64
+long_and: dest:i src1:i src2:i len:4
+long_or: dest:i src1:i src2:i len:4
+long_xor: dest:i src1:i src2:i len:4
+long_shl: dest:i src1:i src2:i len:4
+long_shr: dest:i src1:i src2:i len:4
+long_shr_un: dest:i src1:i src2:i len:4
+long_neg: dest:i src1:i len:4
+long_not: dest:i src1:i len:4
+long_add_imm: dest:i src1:i len:12
+long_sub_imm: dest:i src1:i len:12
+long_mul_imm: dest:i src1:i len:12
+long_and_imm: dest:i src1:i len:12
+long_or_imm: dest:i src1:i len:12
+long_xor_imm: dest:i src1:i len:12
+long_shl_imm: dest:i src1:i len:12
+long_shr_imm: dest:i src1:i len:12
+long_shr_un_imm: dest:i src1:i len:12
+long_add_ovf: dest:i src1:i src2:i len:16
+long_add_ovf_un: dest:i src1:i src2:i len:16
+long_mul_ovf: dest:i src1:i src2:i len:16
+long_mul_ovf_un: dest:i src1:i src2:i len:16
+long_sub_ovf: dest:i src1:i src2:i len:16
+long_sub_ovf_un: dest:i src1:i src2:i len:16
+lcompare: src1:i src2:i len:4
+lcompare_imm: src1:i len:20
+long_beq: len:4
+long_bge: len:4
+long_bgt: len:4
+long_ble: len:4
+long_blt: len:4
+long_bne_un: len:4
+long_bge_un: len:4
+long_bgt_un: len:4
+long_ble_un: len:4
+long_blt_un: len:4
+long_ceq: dest:i len:12
+long_cgt: dest:i len:12
+long_cgt_un: dest:i len:12
+long_clt: dest:i len:12
+long_clt_un: dest:i len:12
+long_conv_to_i1: dest:i src1:i len:4
+long_conv_to_i2: dest:i src1:i len:4
+long_conv_to_u1: dest:i src1:i len:4
+long_conv_to_u2: dest:i src1:i len:4
+long_conv_to_r8: dest:f src1:i len:8
+long_conv_to_r4: dest:f src1:i len:12
+loadi8_membase: dest:i src1:b len:12
+storei8_membase_imm: dest:b  len:20
+storei8_membase_reg: dest:b src1:i len:12
+long_conv_to_r_un: dest:f src1:i len:8
+arm_setfreg_r4: dest:f src1:f len:8
+localloc_imm: dest:i len:64
+arm64_cbzw: src1:i len:16
+arm64_cbzx: src1:i len:16
+arm64_cbnzw: src1:i len:16
+arm64_cbnzx: src1:i len:16
+
+atomic_add_new_i4: dest:i src1:i src2:i len:32
+atomic_add_new_i8: dest:i src1:i src2:i len:32
+atomic_exchange_i4: dest:i src1:i src2:i len:32
+atomic_exchange_i8: dest:i src1:i src2:i len:32
+atomic_cas_i4: dest:i src1:i src2:i src3:i len:32
+atomic_cas_i8: dest:i src1:i src2:i src3:i len:32
+
+
diff --git a/mono/mini/exceptions-arm64.c b/mono/mini/exceptions-arm64.c
new file mode 100644 (file)
index 0000000..333fd13
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../mono-extensions/mono/mini/exceptions-arm64.c"
index 8c13a6171dd947081cc78d7eb28b58ab8a8618b3..b3a4cc8b78b06658dd2f1bf7734dd35beb801c54 100644 (file)
@@ -20,7 +20,7 @@ sub INST_MAX   () {return 6;}
 
 # this must include all the #defines used in mini-ops.h
 my @defines = qw (__i386__ __x86_64__ __ppc__ __powerpc__ __ppc64__ __arm__ 
-       __sparc__ sparc __s390__ s390 __ia64__ __alpha__ __mips__);
+       __sparc__ sparc __s390__ s390 __ia64__ __alpha__ __mips__ __aarch64__);
 my %table =();
 my %template_table =();
 my @opcodes = ();
@@ -85,6 +85,9 @@ sub load_opcodes
        if ($arch =~ "__arm__") {
                $arch_define = "TARGET_ARM";
        }
+       if ($arch =~ "__aarch64__") {
+               $arch_define = "TARGET_ARM64";
+       }
 
        parse_file ($arch_define, "$srcdir/mini-ops.h");
        return;
index d945a39b8f2e4e900c08968e3465ee390e17c6bb..43bd17e2fa499d3fe6904a97f71492646718b10b 100644 (file)
@@ -66,10 +66,14 @@ opnames[] = {
 #endif /* DISABLE_LOGGING */
 
 #if defined(__i386__) || defined(__x86_64__)
+#ifndef TARGET_ARM64
 #define emit_debug_info  TRUE
 #else
 #define emit_debug_info  FALSE
 #endif
+#else
+#define emit_debug_info  FALSE
+#endif
 
 /*This enables us to use the right tooling when building the cross compiler for iOS.*/
 #if defined (__APPLE__) && defined (TARGET_ARM) && (defined(__i386__) || defined(__x86_64__))
@@ -237,6 +241,12 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
 #  else
 #    define AS_CMD "as -gstabs"
 #  endif
+#elif defined (TARGET_ARM64)
+#  if defined (__APPLE__)
+#    define AS_CMD "clang -c -arch arm64 -g -x assembler"
+#  else
+#    define AS_CMD "as -gstabs"
+#  endif
 #elif defined(__mips__) && (_MIPS_SIM == _ABIO32)
 #define AS_CMD "as -mips32"
 #elif defined(__ppc64__)
@@ -275,7 +285,7 @@ mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
        cmd = g_strdup_printf (ARCH_PREFIX DIS_CMD " %s %s", objdump_args, o_file);
        unused = system (cmd);
        g_free (cmd);
-       
+
 #ifndef HOST_WIN32
        unlink (o_file);
        unlink (as_file);
index 2e35b7ab17f8ef7677be8b3e9db35455f0670e71..1ecf79c9ac355a72f79b02ec999f8d1e724570ed 100644 (file)
@@ -1953,10 +1953,26 @@ emit_push_lmf (MonoCompile *cfg)
                }
 #else
                lmf_ins = mono_get_lmf_addr_intrinsic (cfg);
-               if (lmf_ins) 
+               if (lmf_ins) {
                        MONO_ADD_INS (cfg->cbb, lmf_ins);
-               else
+               } else {
+#ifdef TARGET_IOS
+                       MonoInst *args [16], *jit_tls_ins, *ins;
+
+                       /* Inline mono_get_lmf_addr () */
+                       /* jit_tls = pthread_getspecific (mono_jit_tls_id); lmf_addr = &jit_tls->lmf; */
+
+                       /* Load mono_jit_tls_id */
+                       EMIT_NEW_AOTCONST (cfg, args [0], MONO_PATCH_INFO_JIT_TLS_ID, NULL);
+                       /* call pthread_getspecific () */
+                       jit_tls_ins = mono_emit_jit_icall (cfg, pthread_getspecific, args);
+                       /* lmf_addr = &jit_tls->lmf */
+                       EMIT_NEW_BIALU_IMM (cfg, ins, OP_PADD_IMM, cfg->lmf_addr_var->dreg, jit_tls_ins->dreg, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
+                       lmf_ins = ins;
+#else
                        lmf_ins = mono_emit_jit_icall (cfg, mono_get_lmf_addr, NULL);
+#endif
+               }
 #endif
                lmf_ins->dreg = cfg->lmf_addr_var->dreg;
 
@@ -5686,10 +5702,10 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                if (args [0]->opcode == OP_GOT_ENTRY) {
                        pi = args [0]->inst_p1;
                        g_assert (pi->opcode == OP_PATCH_INFO);
-                       g_assert ((int)pi->inst_p1 == MONO_PATCH_INFO_LDSTR);
+                       g_assert (GPOINTER_TO_INT (pi->inst_p1) == MONO_PATCH_INFO_LDSTR);
                        ji = pi->inst_p0;
                } else {
-                       g_assert ((int)args [0]->inst_p1 == MONO_PATCH_INFO_LDSTR);
+                       g_assert (GPOINTER_TO_INT (args [0]->inst_p1) == MONO_PATCH_INFO_LDSTR);
                        ji = args [0]->inst_p0;
                }
 
index a005fc98ad4eadfbee8b53847b24939e41ef6718..6d52aecf6da191d0a89a555015a7a97f31d32a4b 100644 (file)
@@ -19,6 +19,8 @@
 #include "mini-ia64.h"
 #elif defined(TARGET_ARM)
 #include "mini-arm.h"
+#elif defined(TARGET_ARM64)
+#include "mini-arm64.h"
 #elif defined(__mips__)
 #include "mini-mips.h"
 #else
diff --git a/mono/mini/mini-arm64.c b/mono/mini/mini-arm64.c
new file mode 100644 (file)
index 0000000..517f6c6
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../mono-extensions/mono/mini/mini-arm64.c"
diff --git a/mono/mini/mini-arm64.h b/mono/mini/mini-arm64.h
new file mode 100644 (file)
index 0000000..a963c75
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../mono-extensions/mono/mini/mini-arm64.h"
index 48fac064cbdc675bdf85b5d7a42d143688b809bb..6e5bf2f8586b331670c76f02325d0cb7585f3d95 100644 (file)
@@ -1065,8 +1065,9 @@ assign_reg (MonoCompile *cfg, MonoRegState *rs, int reg, int hreg, int bank)
        else {
                g_assert (reg >= MONO_MAX_IREGS);
                g_assert (hreg < MONO_MAX_IREGS);
-#ifndef TARGET_ARM
+#if !defined(TARGET_ARM) && !defined(TARGET_ARM64)
                /* this seems to trigger a gcc compilation bug sometime (hreg is 0) */
+               /* On arm64, rgctx_reg is a global hreg, and it is used to pass an argument */
                g_assert (! is_global_ireg (hreg));
 #endif
 
@@ -1124,7 +1125,7 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                desc_to_fixed_reg_inited = TRUE;
 
                /* Validate the cpu description against the info in mini-ops.h */
-#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM) || defined(TARGET_ARM64)
                for (i = OP_LOAD; i < OP_LAST; ++i) {
                        const char *ispec;
 
index bc6a1aabb6c037c6cc5487edbbf7fac0c160404e..a2e1f2f602962a8cbbfd3298c117031e0e00e691 100644 (file)
@@ -436,6 +436,9 @@ static int callee_saved_regs [] = { AMD64_RBP, AMD64_RBX, AMD64_R12, AMD64_R13,
 static int callee_saved_regs [] = { X86_EBX, X86_ESI, X86_EDI };
 #elif defined(TARGET_ARM)
 static int callee_saved_regs [] = { ARMREG_V1, ARMREG_V2, ARMREG_V3, ARMREG_V4, ARMREG_V5, ARMREG_V7, ARMREG_FP };
+#elif defined(TARGET_ARM64)
+// FIXME:
+static int callee_saved_regs [] = { };
 #elif defined(TARGET_S390X)
 static int callee_saved_regs [] = { s390_r6, s390_r7, s390_r8, s390_r9, s390_r10, s390_r11, s390_r12, s390_r13, s390_r14 };
 #endif
index bccdb295d44e363a3d6ea038531d1a05f8b6821c..b1a31ee16d760a892f4782aa404a173625e0442f 100644 (file)
@@ -1033,9 +1033,11 @@ MINI_OP(OP_PPC_SUBFZE,             "ppc_subfze", IREG, IREG, NONE)
 MINI_OP(OP_CHECK_FINITE,           "ppc_check_finite", NONE, IREG, NONE)
 #endif
 
-#if defined(TARGET_ARM)
+#if defined(TARGET_ARM) || defined(TARGET_ARM64)
 MINI_OP(OP_ARM_RSBS_IMM,            "arm_rsbs_imm", IREG, IREG, NONE)
 MINI_OP(OP_ARM_RSC_IMM,             "arm_rsc_imm", IREG, IREG, NONE)
+/* Set dreg to an r4 value */
+MINI_OP(OP_ARM_SETFREG_R4,             "arm_setfreg_r4", FREG, FREG, NONE)
 #endif
 
 #if defined(__sparc__) || defined(sparc)
@@ -1238,6 +1240,15 @@ MINI_OP(OP_MIPS_COND_EXC_INC, "mips_cond_exc_inc", NONE, IREG, IREG)
 
 #endif
 
+#if defined(TARGET_ARM64)
+/* Branch if sreg1 == 0 */
+MINI_OP(OP_ARM64_CBZW, "arm64_cbzw", NONE, IREG, NONE)
+MINI_OP(OP_ARM64_CBZX, "arm64_cbzx", NONE, IREG, NONE)
+/* Branch if sreg1 != 0 */
+MINI_OP(OP_ARM64_CBNZW, "arm64_cbnzw", NONE, IREG, NONE)
+MINI_OP(OP_ARM64_CBNZX, "arm64_cbnzx", NONE, IREG, NONE)
+#endif
+
 /* Same as OUTARG_VT, but has a dreg */
 #ifdef ENABLE_LLVM
 MINI_OP(OP_LLVM_OUTARG_VT,     "llvm_outarg_vt", IREG, VREG, NONE)
diff --git a/mono/mini/tramp-arm64.c b/mono/mini/tramp-arm64.c
new file mode 100644 (file)
index 0000000..1650437
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../mono-extensions/mono/mini/tramp-arm64.c"
index 018ad903e40307776f205a93c9962bc66d260e4b..87b71984b50aeede7075664d4c8bc1207829a17c 100644 (file)
@@ -56,6 +56,15 @@ static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
 #define NUM_REGS 272
 #define DWARF_DATA_ALIGN (-4)
 #define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (ARMREG_LR))
+#elif defined(TARGET_ARM64)
+/* +1 is for pc */
+#define NUM_REGS (32 + 1)
+#define DWARF_DATA_ALIGN (-8)
+#define DWARF_PC_REG 32
+static int map_hw_reg_to_dwarf_reg [] = {
+       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+       16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
+};
 #elif defined (TARGET_X86)
 #ifdef __APPLE__
 /*