diff options
author | Sverker Eriksson <[email protected]> | 2012-07-04 18:52:08 +0200 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2012-07-04 18:52:55 +0200 |
commit | 1bc0714f0146cedf7b407c54dbd79817f3b9294c (patch) | |
tree | d85c5f0001ce8dd5a428e29b69c5d6d569e78209 | |
parent | 14f6a66f6410e1665ad39e95158420b0a45634d6 (diff) | |
parent | b8489354a77dc41f707f85b5b31d3fabd788d69e (diff) | |
download | otp-1bc0714f0146cedf7b407c54dbd79817f3b9294c.tar.gz otp-1bc0714f0146cedf7b407c54dbd79817f3b9294c.tar.bz2 otp-1bc0714f0146cedf7b407c54dbd79817f3b9294c.zip |
Merge branch 'sverk/hipe-arm-fix' into maint
* sverk/hipe-arm-fix:
hipe_arm.c: remove dead code
Workaround gcc bug affecting ARM debug build
Fix compile error of HIPE enabled DEBUG emulator for ARM
Fix hipe bif calling bug on ARM
Add armv7l and armv5tejl as a recognized ARM architectures
OTP-10137
-rw-r--r-- | erts/configure.in | 2 | ||||
-rw-r--r-- | erts/emulator/Makefile.in | 5 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_arm.c | 89 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_arm_bifs.m4 | 18 |
4 files changed, 38 insertions, 76 deletions
diff --git a/erts/configure.in b/erts/configure.in index 500d1490e9..b3289bf84c 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -618,6 +618,8 @@ case $chk_arch_ in armv5b) ARCH=arm;; armv5teb) ARCH=arm;; armv5tel) ARCH=arm;; + armv5tejl) ARCH=arm;; + armv7l) ARCH=arm;; tile) ARCH=tile;; *) ARCH=noarch;; esac diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 04069b517a..985ef72517 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -924,6 +924,11 @@ $(TTF_DIR)/hipe_arm_bifs.S: hipe/hipe_arm_bifs.m4 hipe/hipe_arm_asm.m4 \ $(OBJDIR)/hipe_arm_bifs.o: $(TTF_DIR)/hipe_arm_bifs.S \ $(TTF_DIR)/hipe_literals.h +# Use -fomit-frame-pointer to work around gcc (v4.5.2) bug causing +# "error: r7 cannot be used in asm here" for DEBUG build. +$(OBJDIR)/hipe_arm.o: hipe/hipe_arm.c + $(CC) $(subst O2,O3, $(CFLAGS)) -fomit-frame-pointer $(INCLUDES) -c $< -o $@ + # end of HiPE section ######################################## diff --git a/erts/emulator/hipe/hipe_arm.c b/erts/emulator/hipe/hipe_arm.c index e20a8a7969..651d0e3a75 100644 --- a/erts/emulator/hipe/hipe_arm.c +++ b/erts/emulator/hipe/hipe_arm.c @@ -181,11 +181,9 @@ void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process * curseg.base = base; curseg.code_pos = base; curseg.tramp_pos = (unsigned int*)((char*)base + SEGMENT_NRBYTES); -#if defined(__arm__) curseg.tramp_pos -= 2; curseg.tramp_pos[0] = 0xE51FF004; /* ldr pc, [pc,#-4] */ curseg.tramp_pos[1] = (unsigned int)&nbif_callemu; -#endif address = try_alloc(nrwords, nrcallees, callees, trampvec); if (!address) { @@ -214,11 +212,9 @@ static unsigned int *alloc_stub(Uint nrwords, unsigned int **tramp_callemu) curseg.base = base; curseg.code_pos = base; curseg.tramp_pos = (unsigned int*)((char*)base + SEGMENT_NRBYTES); -#if defined(__arm__) curseg.tramp_pos -= 2; curseg.tramp_pos[0] = 0xE51FF004; /* ldr pc, [pc,#-4] */ curseg.tramp_pos[1] = (unsigned int)&nbif_callemu; -#endif address = try_alloc(nrwords, 0, NIL, NULL); if (!address) { @@ -269,10 +265,8 @@ int hipe_patch_insn(void *address, Uint32 value, Eterm type) void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity) { unsigned int *code; -#if defined(__arm__) unsigned int *tramp_callemu; int callemu_offset; -#endif /* * Native code calls BEAM via a stub looking as follows: @@ -288,13 +282,6 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity) * (Trampolines are allowed to modify r12, but they don't.) */ -#if !defined(__arm__) - /* verify that 'ba' can reach nbif_callemu */ - if ((unsigned long)&nbif_callemu & ~0x01FFFFFCUL) - abort(); -#endif - -#if defined(__arm__) code = alloc_stub(4, &tramp_callemu); callemu_offset = ((int)&nbif_callemu - ((int)&code[2] + 8)) >> 2; if (!(callemu_offset >= -0x00800000 && callemu_offset <= 0x007FFFFF)) { @@ -302,11 +289,7 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity) if (!(callemu_offset >= -0x00800000 && callemu_offset <= 0x007FFFFF)) abort(); } -#else - code = alloc_stub(4, &trampoline); -#endif -#if defined(__arm__) /* mov r0, #beamArity */ code[0] = 0xE3A00000 | (beamArity & 0xFF); /* ldr r8, [pc,#0] // beamAddress */ @@ -315,16 +298,6 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity) code[2] = 0xEA000000 | (callemu_offset & 0x00FFFFFF); /* .long beamAddress */ code[3] = (unsigned int)beamAddress; -#else - /* addi r12,0,beamAddress@l */ - code[0] = 0x39800000 | ((unsigned long)beamAddress & 0xFFFF); - /* addi r0,0,beamArity */ - code[1] = 0x38000000 | (beamArity & 0x7FFF); - /* addis r12,r12,beamAddress@ha */ - code[2] = 0x3D8C0000 | at_ha((unsigned long)beamAddress); - /* ba nbif_callemu */ - code[3] = 0x48000002 | (unsigned long)&nbif_callemu; -#endif hipe_flush_icache_range(code, 4*sizeof(int)); @@ -334,60 +307,32 @@ void *hipe_make_native_stub(void *beamAddress, unsigned int beamArity) static void patch_b(Uint32 *address, Sint32 offset, Uint32 AA) { Uint32 oldI = *address; -#if defined(__arm__) Uint32 newI = (oldI & 0xFF000000) | (offset & 0x00FFFFFF); -#else - Uint32 newI = (oldI & 0xFC000001) | ((offset & 0x00FFFFFF) << 2) | (AA & 2); -#endif *address = newI; hipe_flush_icache_word(address); } int hipe_patch_call(void *callAddress, void *destAddress, void *trampoline) { -#if !defined(__arm__) - if ((Uint32)destAddress == ((Uint32)destAddress & 0x01FFFFFC)) { - /* The destination is in the [0,32MB[ range. - We can reach it with a ba/bla instruction. - This is the typical case for BIFs and primops. - It's also common for trap-to-BEAM stubs (on ppc32). */ - patch_b((Uint32*)callAddress, (Uint32)destAddress >> 2, 2); + Sint32 destOffset = ((Sint32)destAddress - ((Sint32)callAddress+8)) >> 2; + if (destOffset >= -0x800000 && destOffset <= 0x7FFFFF) { + /* The destination is within a [-32MB,+32MB[ range from us. + We can reach it with a b/bl instruction. + This is typical for nearby Erlang code. */ + patch_b((Uint32*)callAddress, destOffset, 0); } else { -#endif -#if defined(__arm__) - Sint32 destOffset = ((Sint32)destAddress - ((Sint32)callAddress+8)) >> 2; -#else - Sint32 destOffset = ((Sint32)destAddress - (Sint32)callAddress) >> 2; -#endif - if (destOffset >= -0x800000 && destOffset <= 0x7FFFFF) { - /* The destination is within a [-32MB,+32MB[ range from us. - We can reach it with a b/bl instruction. - This is typical for nearby Erlang code. */ - patch_b((Uint32*)callAddress, destOffset, 0); - } else { - /* The destination is too distant for b/bl/ba/bla. - Must do a b/bl to the trampoline. */ -#if defined(__arm__) - Sint32 trampOffset = ((Sint32)trampoline - ((Sint32)callAddress+8)) >> 2; -#else - Sint32 trampOffset = ((Sint32)trampoline - (Sint32)callAddress) >> 2; -#endif - if (trampOffset >= -0x800000 && trampOffset <= 0x7FFFFF) { - /* Update the trampoline's address computation. - (May be redundant, but we can't tell.) */ -#if defined(__arm__) - patch_imm32((Uint32*)trampoline+1, (Uint32)destAddress); -#else - patch_li((Uint32*)trampoline, (Uint32)destAddress); -#endif - /* Update this call site. */ - patch_b((Uint32*)callAddress, trampOffset, 0); - } else - return -1; - } -#if !defined(__arm__) + /* The destination is too distant for b/bl. + Must do a b/bl to the trampoline. */ + Sint32 trampOffset = ((Sint32)trampoline - ((Sint32)callAddress+8)) >> 2; + if (trampOffset >= -0x800000 && trampOffset <= 0x7FFFFF) { + /* Update the trampoline's address computation. + (May be redundant, but we can't tell.) */ + patch_imm32((Uint32*)trampoline+1, (Uint32)destAddress); + /* Update this call site. */ + patch_b((Uint32*)callAddress, trampOffset, 0); + } else + return -1; } -#endif return 0; } diff --git a/erts/emulator/hipe/hipe_arm_bifs.m4 b/erts/emulator/hipe/hipe_arm_bifs.m4 index e0c6f09796..17c013f1fb 100644 --- a/erts/emulator/hipe/hipe_arm_bifs.m4 +++ b/erts/emulator/hipe/hipe_arm_bifs.m4 @@ -27,7 +27,7 @@ include(`hipe/hipe_arm_asm.m4') .p2align 2 `#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) -# define CALL_BIF(F) mov r14, #F; str r14, [r0, #P_BIF_CALLEE]; bl hipe_debug_bif_wrapper +# define CALL_BIF(F) ldr r14, =F; str r14, [r0, #P_BIF_CALLEE]; bl hipe_debug_bif_wrapper #else # define CALL_BIF(F) bl F #endif' @@ -67,6 +67,7 @@ $1: RESTORE_CONTEXT_BIF beq nbif_1_simple_exception NBIF_RET(1) + .ltorg /* needed by LDR in debug version of `CALL_BIF' */ .size $1, .-$1 .type $1, %function #endif') @@ -95,6 +96,7 @@ $1: RESTORE_CONTEXT_BIF beq nbif_2_simple_exception NBIF_RET(2) + .ltorg .size $1, .-$1 .type $1, %function #endif') @@ -125,6 +127,7 @@ $1: RESTORE_CONTEXT_BIF beq nbif_3_simple_exception NBIF_RET(3) + .ltorg .size $1, .-$1 .type $1, %function #endif') @@ -149,6 +152,7 @@ $1: RESTORE_CONTEXT_BIF beq nbif_0_simple_exception NBIF_RET(0) + .ltorg .size $1, .-$1 .type $1, %function #endif') @@ -173,7 +177,8 @@ $1: /* Save caller-save registers and call the C function. */ SAVE_CONTEXT_GC - bl $2 + /* ignore empty BIF__ARGS */ + CALL_BIF($2) TEST_GOT_MBUF(0) /* Restore registers. */ @@ -195,7 +200,9 @@ $1: /* Save caller-save registers and call the C function. */ SAVE_CONTEXT_GC - bl $2 + str r1, [r0, #P_ARG0] /* Store BIF__ARGS in def_arg_reg[] */ + add r1, r0, #P_ARG0 + CALL_BIF($2) TEST_GOT_MBUF(1) /* Restore registers. Check for exception. */ @@ -220,7 +227,10 @@ $1: /* Save caller-save registers and call the C function. */ SAVE_CONTEXT_GC - bl $2 + str r1, [r0, #P_ARG0] /* Store BIF__ARGS in def_arg_reg[] */ + str r2, [r0, #P_ARG1] + add r1, r0, #P_ARG0 + CALL_BIF($2) TEST_GOT_MBUF(2) /* Restore registers. Check for exception. */ |