From 924fb2a51a1e0c143dbb8d82ec14e2065c614e2d Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Sat, 19 Apr 2014 20:16:47 +0200 Subject: [PATCH] [arm64] Add JIT support. --- mono/arch/arm64/arm64-codegen.h | 3 + mono/mini/Makefile.am.in | 16 ++ mono/mini/cpu-arm64.md | 424 ++++++++++++++++++++++++++++++++ mono/mini/exceptions-arm64.c | 1 + mono/mini/genmdesc.pl | 5 +- mono/mini/helpers.c | 12 +- mono/mini/method-to-ir.c | 24 +- mono/mini/mini-arch.h | 2 + mono/mini/mini-arm64.c | 1 + mono/mini/mini-arm64.h | 1 + mono/mini/mini-codegen.c | 5 +- mono/mini/mini-gc.c | 3 + mono/mini/mini-ops.h | 13 +- mono/mini/tramp-arm64.c | 1 + mono/mini/unwind.c | 9 + 15 files changed, 511 insertions(+), 9 deletions(-) create mode 100644 mono/arch/arm64/arm64-codegen.h create mode 100644 mono/mini/cpu-arm64.md create mode 100644 mono/mini/exceptions-arm64.c create mode 100644 mono/mini/mini-arm64.c create mode 100644 mono/mini/mini-arm64.h create mode 100644 mono/mini/tramp-arm64.c diff --git a/mono/arch/arm64/arm64-codegen.h b/mono/arch/arm64/arm64-codegen.h new file mode 100644 index 00000000000..259ff967407 --- /dev/null +++ b/mono/arch/arm64/arm64-codegen.h @@ -0,0 +1,3 @@ +#include "../../../../mono-extensions/mono/arch/arm64/arm64-codegen.h" + + diff --git a/mono/mini/Makefile.am.in b/mono/mini/Makefile.am.in index 55e5f14abf2..cd935b50bb7 100755 --- a/mono/mini/Makefile.am.in +++ b/mono/mini/Makefile.am.in @@ -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 index 00000000000..d57b6eeda2b --- /dev/null +++ b/mono/mini/cpu-arm64.md @@ -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 index 00000000000..333fd13b754 --- /dev/null +++ b/mono/mini/exceptions-arm64.c @@ -0,0 +1 @@ +#include "../../../mono-extensions/mono/mini/exceptions-arm64.c" diff --git a/mono/mini/genmdesc.pl b/mono/mini/genmdesc.pl index 8c13a6171dd..b3a4cc8b78b 100644 --- a/mono/mini/genmdesc.pl +++ b/mono/mini/genmdesc.pl @@ -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; diff --git a/mono/mini/helpers.c b/mono/mini/helpers.c index d945a39b8f2..43bd17e2fa4 100644 --- a/mono/mini/helpers.c +++ b/mono/mini/helpers.c @@ -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); diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 2e35b7ab17f..1ecf79c9ac3 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -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; } diff --git a/mono/mini/mini-arch.h b/mono/mini/mini-arch.h index a005fc98ad4..6d52aecf6da 100644 --- a/mono/mini/mini-arch.h +++ b/mono/mini/mini-arch.h @@ -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 index 00000000000..517f6c68a9d --- /dev/null +++ b/mono/mini/mini-arm64.c @@ -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 index 00000000000..a963c75d51c --- /dev/null +++ b/mono/mini/mini-arm64.h @@ -0,0 +1 @@ +#include "../../../mono-extensions/mono/mini/mini-arm64.h" diff --git a/mono/mini/mini-codegen.c b/mono/mini/mini-codegen.c index 48fac064cbd..6e5bf2f8586 100644 --- a/mono/mini/mini-codegen.c +++ b/mono/mini/mini-codegen.c @@ -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; diff --git a/mono/mini/mini-gc.c b/mono/mini/mini-gc.c index bc6a1aabb6c..a2e1f2f6029 100644 --- a/mono/mini/mini-gc.c +++ b/mono/mini/mini-gc.c @@ -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 diff --git a/mono/mini/mini-ops.h b/mono/mini/mini-ops.h index bccdb295d44..b1a31ee16d7 100644 --- a/mono/mini/mini-ops.h +++ b/mono/mini/mini-ops.h @@ -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 index 00000000000..16504375d84 --- /dev/null +++ b/mono/mini/tramp-arm64.c @@ -0,0 +1 @@ +#include "../../../mono-extensions/mono/mini/tramp-arm64.c" diff --git a/mono/mini/unwind.c b/mono/mini/unwind.c index 018ad903e40..87b71984b50 100644 --- a/mono/mini/unwind.c +++ b/mono/mini/unwind.c @@ -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__ /* -- 2.25.1