diff options
author | 2016-12-06 12:42:21 +0000 | |
---|---|---|
committer | 2016-12-06 12:42:21 +0000 | |
commit | 07830e11b718774c474d5f618ecfb29e238e47f7 (patch) | |
tree | d09fee8d2915d5355aa367955610235c64269321 | |
parent | d1aa2912f3acdd9f47acd98e947818b09c2b349a (diff) | |
parent | ac50aab516a1ab0977fbc961f53f4edd29a891e5 (diff) |
Merge "Mterp/arm: Add CFI directives."
-rw-r--r-- | runtime/interpreter/mterp/arm/entry.S | 15 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm/footer.S | 3 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm/header.S | 21 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm/op_double_to_long.S | 63 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm/op_float_to_long.S | 48 | ||||
-rw-r--r-- | runtime/interpreter/mterp/out/mterp_arm.S | 174 | ||||
-rw-r--r-- | test/422-type-conversion/src/Main.java | 4 |
7 files changed, 179 insertions, 149 deletions
diff --git a/runtime/interpreter/mterp/arm/entry.S b/runtime/interpreter/mterp/arm/entry.S index a6b131d219..e53c0544c6 100644 --- a/runtime/interpreter/mterp/arm/entry.S +++ b/runtime/interpreter/mterp/arm/entry.S @@ -31,10 +31,19 @@ * */ -ExecuteMterpImpl: - .fnstart - .save {r3-r10,fp,lr} +ENTRY ExecuteMterpImpl stmfd sp!, {r3-r10,fp,lr} @ save 10 regs, (r3 just to align 64) + .cfi_adjust_cfa_offset 40 + .cfi_rel_offset r3, 0 + .cfi_rel_offset r4, 4 + .cfi_rel_offset r5, 8 + .cfi_rel_offset r6, 12 + .cfi_rel_offset r7, 16 + .cfi_rel_offset r8, 20 + .cfi_rel_offset r9, 24 + .cfi_rel_offset r10, 28 + .cfi_rel_offset fp, 32 + .cfi_rel_offset lr, 36 /* Remember the return register */ str r3, [r2, #SHADOWFRAME_RESULT_REGISTER_OFFSET] diff --git a/runtime/interpreter/mterp/arm/footer.S b/runtime/interpreter/mterp/arm/footer.S index cd32ea2e28..c6801e5dda 100644 --- a/runtime/interpreter/mterp/arm/footer.S +++ b/runtime/interpreter/mterp/arm/footer.S @@ -294,6 +294,5 @@ MterpProfileActive: mov r0, rINST @ restore return value ldmfd sp!, {r3-r10,fp,pc} @ restore 10 regs and return - .fnend - .size ExecuteMterpImpl, .-ExecuteMterpImpl + END ExecuteMterpImpl diff --git a/runtime/interpreter/mterp/arm/header.S b/runtime/interpreter/mterp/arm/header.S index 039bcbe262..597d9d46a5 100644 --- a/runtime/interpreter/mterp/arm/header.S +++ b/runtime/interpreter/mterp/arm/header.S @@ -287,3 +287,24 @@ unspecified registers or condition codes. .macro REFRESH_IBASE ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] .endm + +/* + * cfi support macros. + */ +.macro ENTRY name + .arm + .type \name, #function + .hidden \name // Hide this as a global symbol, so we do not incur plt calls. + .global \name + /* Cache alignment for function entry */ + .balign 16 +\name: + .cfi_startproc + .fnstart +.endm + +.macro END name + .fnend + .cfi_endproc + .size \name, .-\name +.endm diff --git a/runtime/interpreter/mterp/arm/op_double_to_long.S b/runtime/interpreter/mterp/arm/op_double_to_long.S index b10081052e..19ff7235e0 100644 --- a/runtime/interpreter/mterp/arm/op_double_to_long.S +++ b/runtime/interpreter/mterp/arm/op_double_to_long.S @@ -1,4 +1,3 @@ -@include "arm/unopWide.S" {"instr":"bl __aeabi_d2lz"} %include "arm/unopWide.S" {"instr":"bl d2l_doconv"} %break @@ -10,43 +9,25 @@ * to modest integer. The EABI convert function isn't doing this for us. */ d2l_doconv: - stmfd sp!, {r4, r5, lr} @ save regs - mov r3, #0x43000000 @ maxlong, as a double (high word) - add r3, #0x00e00000 @ 0x43e00000 - mov r2, #0 @ maxlong, as a double (low word) - sub sp, sp, #4 @ align for EABI - mov r4, r0 @ save a copy of r0 - mov r5, r1 @ and r1 - bl __aeabi_dcmpge @ is arg >= maxlong? - cmp r0, #0 @ nonzero == yes - mvnne r0, #0 @ return maxlong (7fffffffffffffff) - mvnne r1, #0x80000000 - bne 1f - - mov r0, r4 @ recover arg - mov r1, r5 - mov r3, #0xc3000000 @ minlong, as a double (high word) - add r3, #0x00e00000 @ 0xc3e00000 - mov r2, #0 @ minlong, as a double (low word) - bl __aeabi_dcmple @ is arg <= minlong? - cmp r0, #0 @ nonzero == yes - movne r0, #0 @ return minlong (8000000000000000) - movne r1, #0x80000000 - bne 1f - - mov r0, r4 @ recover arg - mov r1, r5 - mov r2, r4 @ compare against self - mov r3, r5 - bl __aeabi_dcmpeq @ is arg == self? - cmp r0, #0 @ zero == no - moveq r1, #0 @ return zero for NaN - beq 1f - - mov r0, r4 @ recover arg - mov r1, r5 - bl __aeabi_d2lz @ convert double to long - -1: - add sp, sp, #4 - ldmfd sp!, {r4, r5, pc} + ubfx r2, r1, #20, #11 @ grab the exponent + movw r3, #0x43e + cmp r2, r3 @ MINLONG < x > MAXLONG? + bhs d2l_special_cases + b __aeabi_d2lz @ tail call to convert double to long +d2l_special_cases: + movw r3, #0x7ff + cmp r2, r3 + beq d2l_maybeNaN @ NaN? +d2l_notNaN: + adds r1, r1, r1 @ sign bit to carry + mov r0, #0xffffffff @ assume maxlong for lsw + mov r1, #0x7fffffff @ assume maxlong for msw + adc r0, r0, #0 + adc r1, r1, #0 @ convert maxlong to minlong if exp negative + bx lr @ return +d2l_maybeNaN: + orrs r3, r0, r1, lsl #12 + beq d2l_notNaN @ if fraction is non-zero, it's a NaN + mov r0, #0 + mov r1, #0 + bx lr @ return 0 for NaN diff --git a/runtime/interpreter/mterp/arm/op_float_to_long.S b/runtime/interpreter/mterp/arm/op_float_to_long.S index 5c8680f133..1770ea04b0 100644 --- a/runtime/interpreter/mterp/arm/op_float_to_long.S +++ b/runtime/interpreter/mterp/arm/op_float_to_long.S @@ -1,4 +1,3 @@ -@include "arm/unopWider.S" {"instr":"bl __aeabi_f2lz"} %include "arm/unopWider.S" {"instr":"bl f2l_doconv"} %break @@ -10,30 +9,23 @@ * to modest integer. The EABI convert function isn't doing this for us. */ f2l_doconv: - stmfd sp!, {r4, lr} - mov r1, #0x5f000000 @ (float)maxlong - mov r4, r0 - bl __aeabi_fcmpge @ is arg >= maxlong? - cmp r0, #0 @ nonzero == yes - mvnne r0, #0 @ return maxlong (7fffffff) - mvnne r1, #0x80000000 - popne {r4, pc} - - mov r0, r4 @ recover arg - mov r1, #0xdf000000 @ (float)minlong - bl __aeabi_fcmple @ is arg <= minlong? - cmp r0, #0 @ nonzero == yes - movne r0, #0 @ return minlong (80000000) - movne r1, #0x80000000 - popne {r4, pc} - - mov r0, r4 @ recover arg - mov r1, r4 - bl __aeabi_fcmpeq @ is arg == self? - cmp r0, #0 @ zero == no - moveq r1, #0 @ return zero for NaN - popeq {r4, pc} - - mov r0, r4 @ recover arg - bl __aeabi_f2lz @ convert float to long - ldmfd sp!, {r4, pc} + ubfx r2, r0, #23, #8 @ grab the exponent + cmp r2, #0xbe @ MININT < x > MAXINT? + bhs f2l_special_cases + b __aeabi_f2lz @ tail call to convert float to long +f2l_special_cases: + cmp r2, #0xff @ NaN or infinity? + beq f2l_maybeNaN +f2l_notNaN: + adds r0, r0, r0 @ sign bit to carry + mov r0, #0xffffffff @ assume maxlong for lsw + mov r1, #0x7fffffff @ assume maxlong for msw + adcs r0, r0, #0 @ convert maxlong to minlong if exp negative + adc r1, r1, #0 @ convert maxlong to minlong if exp negative + bx lr @ return +f2l_maybeNaN: + lsls r3, r0, #9 + beq f2l_notNaN @ if fraction is non-zero, it's a NaN + mov r0, #0 + mov r1, #0 + bx lr @ return 0 for NaN diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S index 4d540d768b..c80d6b98d4 100644 --- a/runtime/interpreter/mterp/out/mterp_arm.S +++ b/runtime/interpreter/mterp/out/mterp_arm.S @@ -295,6 +295,27 @@ unspecified registers or condition codes. ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] .endm +/* + * cfi support macros. + */ +.macro ENTRY name + .arm + .type \name, #function + .hidden \name // Hide this as a global symbol, so we do not incur plt calls. + .global \name + /* Cache alignment for function entry */ + .balign 16 +\name: + .cfi_startproc + .fnstart +.endm + +.macro END name + .fnend + .cfi_endproc + .size \name, .-\name +.endm + /* File: arm/entry.S */ /* * Copyright (C) 2016 The Android Open Source Project @@ -329,10 +350,19 @@ unspecified registers or condition codes. * */ -ExecuteMterpImpl: - .fnstart - .save {r3-r10,fp,lr} +ENTRY ExecuteMterpImpl stmfd sp!, {r3-r10,fp,lr} @ save 10 regs, (r3 just to align 64) + .cfi_adjust_cfa_offset 40 + .cfi_rel_offset r3, 0 + .cfi_rel_offset r4, 4 + .cfi_rel_offset r5, 8 + .cfi_rel_offset r6, 12 + .cfi_rel_offset r7, 16 + .cfi_rel_offset r8, 20 + .cfi_rel_offset r9, 24 + .cfi_rel_offset r10, 28 + .cfi_rel_offset fp, 32 + .cfi_rel_offset lr, 36 /* Remember the return register */ str r3, [r2, #SHADOWFRAME_RESULT_REGISTER_OFFSET] @@ -3664,7 +3694,6 @@ constvalop_long_to_double: .balign 128 .L_op_float_to_long: /* 0x88 */ /* File: arm/op_float_to_long.S */ -@include "arm/unopWider.S" {"instr":"bl __aeabi_f2lz"} /* File: arm/unopWider.S */ /* * Generic 32bit-to-64bit unary operation. Provide an "instr" line @@ -3742,7 +3771,6 @@ constvalop_long_to_double: .balign 128 .L_op_double_to_long: /* 0x8b */ /* File: arm/op_double_to_long.S */ -@include "arm/unopWide.S" {"instr":"bl __aeabi_d2lz"} /* File: arm/unopWide.S */ /* * Generic 64-bit unary operation. Provide an "instr" line that @@ -7386,33 +7414,26 @@ artMterpAsmSisterStart: * to modest integer. The EABI convert function isn't doing this for us. */ f2l_doconv: - stmfd sp!, {r4, lr} - mov r1, #0x5f000000 @ (float)maxlong - mov r4, r0 - bl __aeabi_fcmpge @ is arg >= maxlong? - cmp r0, #0 @ nonzero == yes - mvnne r0, #0 @ return maxlong (7fffffff) - mvnne r1, #0x80000000 - popne {r4, pc} - - mov r0, r4 @ recover arg - mov r1, #0xdf000000 @ (float)minlong - bl __aeabi_fcmple @ is arg <= minlong? - cmp r0, #0 @ nonzero == yes - movne r0, #0 @ return minlong (80000000) - movne r1, #0x80000000 - popne {r4, pc} - - mov r0, r4 @ recover arg - mov r1, r4 - bl __aeabi_fcmpeq @ is arg == self? - cmp r0, #0 @ zero == no - moveq r1, #0 @ return zero for NaN - popeq {r4, pc} - - mov r0, r4 @ recover arg - bl __aeabi_f2lz @ convert float to long - ldmfd sp!, {r4, pc} + ubfx r2, r0, #23, #8 @ grab the exponent + cmp r2, #0xbe @ MININT < x > MAXINT? + bhs f2l_special_cases + b __aeabi_f2lz @ tail call to convert float to long +f2l_special_cases: + cmp r2, #0xff @ NaN or infinity? + beq f2l_maybeNaN +f2l_notNaN: + adds r0, r0, r0 @ sign bit to carry + mov r0, #0xffffffff @ assume maxlong for lsw + mov r1, #0x7fffffff @ assume maxlong for msw + adcs r0, r0, #0 @ convert maxlong to minlong if exp negative + adc r1, r1, #0 @ convert maxlong to minlong if exp negative + bx lr @ return +f2l_maybeNaN: + lsls r3, r0, #9 + beq f2l_notNaN @ if fraction is non-zero, it's a NaN + mov r0, #0 + mov r1, #0 + bx lr @ return 0 for NaN /* continuation for op_double_to_long */ /* @@ -7423,46 +7444,28 @@ f2l_doconv: * to modest integer. The EABI convert function isn't doing this for us. */ d2l_doconv: - stmfd sp!, {r4, r5, lr} @ save regs - mov r3, #0x43000000 @ maxlong, as a double (high word) - add r3, #0x00e00000 @ 0x43e00000 - mov r2, #0 @ maxlong, as a double (low word) - sub sp, sp, #4 @ align for EABI - mov r4, r0 @ save a copy of r0 - mov r5, r1 @ and r1 - bl __aeabi_dcmpge @ is arg >= maxlong? - cmp r0, #0 @ nonzero == yes - mvnne r0, #0 @ return maxlong (7fffffffffffffff) - mvnne r1, #0x80000000 - bne 1f - - mov r0, r4 @ recover arg - mov r1, r5 - mov r3, #0xc3000000 @ minlong, as a double (high word) - add r3, #0x00e00000 @ 0xc3e00000 - mov r2, #0 @ minlong, as a double (low word) - bl __aeabi_dcmple @ is arg <= minlong? - cmp r0, #0 @ nonzero == yes - movne r0, #0 @ return minlong (8000000000000000) - movne r1, #0x80000000 - bne 1f - - mov r0, r4 @ recover arg - mov r1, r5 - mov r2, r4 @ compare against self - mov r3, r5 - bl __aeabi_dcmpeq @ is arg == self? - cmp r0, #0 @ zero == no - moveq r1, #0 @ return zero for NaN - beq 1f - - mov r0, r4 @ recover arg - mov r1, r5 - bl __aeabi_d2lz @ convert double to long - -1: - add sp, sp, #4 - ldmfd sp!, {r4, r5, pc} + ubfx r2, r1, #20, #11 @ grab the exponent + movw r3, #0x43e + cmp r2, r3 @ MINLONG < x > MAXLONG? + bhs d2l_special_cases + b __aeabi_d2lz @ tail call to convert double to long +d2l_special_cases: + movw r3, #0x7ff + cmp r2, r3 + beq d2l_maybeNaN @ NaN? +d2l_notNaN: + adds r1, r1, r1 @ sign bit to carry + mov r0, #0xffffffff @ assume maxlong for lsw + mov r1, #0x7fffffff @ assume maxlong for msw + adcs r0, r0, #0 + adc r1, r1, #0 @ convert maxlong to minlong if exp negative + bx lr @ return +d2l_maybeNaN: + orrs r3, r0, r1, lsl #12 + beq d2l_notNaN @ if fraction is non-zero, it's a NaN + mov r0, #0 + mov r1, #0 + bx lr @ return 0 for NaN .size artMterpAsmSisterStart, .-artMterpAsmSisterStart .global artMterpAsmSisterEnd @@ -12115,6 +12118,17 @@ MterpDone: cmp rPROFILE, #0 bgt MterpProfileActive @ if > 0, we may have some counts to report. ldmfd sp!, {r3-r10,fp,pc} @ restore 10 regs and return + .cfi_restore r3 + .cfi_restore r4 + .cfi_restore r5 + .cfi_restore r6 + .cfi_restore r7 + .cfi_restore r9 + .cfi_restore r9 + .cfi_restore r10 + .cfi_restore fp + .cfi_restore pc + .cfi_adjust_cfa_offset -40 MterpProfileActive: mov rINST, r0 @ stash return value @@ -12126,8 +12140,18 @@ MterpProfileActive: bl MterpAddHotnessBatch @ (method, shadow_frame, self) mov r0, rINST @ restore return value ldmfd sp!, {r3-r10,fp,pc} @ restore 10 regs and return - - .fnend - .size ExecuteMterpImpl, .-ExecuteMterpImpl + .cfi_restore r3 + .cfi_restore r4 + .cfi_restore r5 + .cfi_restore r6 + .cfi_restore r7 + .cfi_restore r9 + .cfi_restore r9 + .cfi_restore r10 + .cfi_restore fp + .cfi_restore pc + .cfi_adjust_cfa_offset -40 + + END ExecuteMterpImpl diff --git a/test/422-type-conversion/src/Main.java b/test/422-type-conversion/src/Main.java index 146f309c81..7754b751ee 100644 --- a/test/422-type-conversion/src/Main.java +++ b/test/422-type-conversion/src/Main.java @@ -390,6 +390,8 @@ public class Main { assertLongEquals(9223372036854775807L, $opt$noinline$FloatToLong(9223372036854775807F)); // 2^63 - 1 assertLongEquals(-9223372036854775808L, $opt$noinline$FloatToLong(-9223372036854775807F)); // -(2^63 - 1) assertLongEquals(-9223372036854775808L, $opt$noinline$FloatToLong(-9223372036854775808F)); // -(2^63) + assertLongEquals(9223371487098961920L, $opt$noinline$FloatToLong(9223371487098961920F)); // Math.nextAfter(2F^63, 0) + assertLongEquals(-9223371487098961920L, $opt$noinline$FloatToLong(-9223371487098961920F)); // Math.nextAfter(-2F^63, 0) assertLongEquals(0L, $opt$noinline$FloatToLong(Float.NaN)); assertLongEquals(9223372036854775807L, $opt$noinline$FloatToLong(Float.POSITIVE_INFINITY)); assertLongEquals(-9223372036854775808L, $opt$noinline$FloatToLong(Float.NEGATIVE_INFINITY)); @@ -469,6 +471,8 @@ public class Main { assertLongEquals(-9223372036854775808L, $opt$noinline$DoubleToLong(-9223372036854775807D)); // -(2^63 - 1) assertLongEquals(-9223372036854775808L, $opt$noinline$DoubleToLong(-9223372036854775808D)); // -(2^63) assertLongEquals(0L, $opt$noinline$DoubleToLong(Double.NaN)); + assertLongEquals(9223372036854774784L, $opt$noinline$DoubleToLong(9223372036854774784D)); // Math.nextAfter(2D^63, 0) + assertLongEquals(-9223372036854774784L, $opt$noinline$DoubleToLong(-9223372036854774784D)); // Math.nextAfter(-2D^63, 0) assertLongEquals(9223372036854775807L, $opt$noinline$DoubleToLong(Double.POSITIVE_INFINITY)); assertLongEquals(-9223372036854775808L, $opt$noinline$DoubleToLong(Double.NEGATIVE_INFINITY)); } |