diff options
author | Andreas Gampe <agampe@google.com> | 2014-05-01 14:38:56 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-05-01 14:55:57 -0700 |
commit | d1104322e5156669767e8b2c3b843ffaff173381 (patch) | |
tree | 3b3e89afb1d616e958ac084a3e75c50d33deccb0 /compiler/utils/arm64 | |
parent | 69cf921f5ab4467fa2c109e30ea5caca2a20790c (diff) | |
download | art-d1104322e5156669767e8b2c3b843ffaff173381.zip art-d1104322e5156669767e8b2c3b843ffaff173381.tar.gz art-d1104322e5156669767e8b2c3b843ffaff173381.tar.bz2 |
ART: aarch64 jni compiler needs to extend small return types
As aarch64 calling convention does not mandate extension on return
values anymore and leaves the upper bits undefined, the jni compiler
needs to sign- or zero-extend the returned values when necessary.
As three architectures need extension now, refactor this fact into a
flag into a virtual method.
Add tests to JniTest that exercise the required extension.
Change-Id: Idebb7c4dedebb852e58ade63e1c2b1eeced23104
Diffstat (limited to 'compiler/utils/arm64')
-rw-r--r-- | compiler/utils/arm64/assembler_arm64.cc | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/compiler/utils/arm64/assembler_arm64.cc b/compiler/utils/arm64/assembler_arm64.cc index 1d87eaa..b4bb979 100644 --- a/compiler/utils/arm64/assembler_arm64.cc +++ b/compiler/utils/arm64/assembler_arm64.cc @@ -467,12 +467,26 @@ void Arm64Assembler::MemoryBarrier(ManagedRegister m_scratch) { #endif } -void Arm64Assembler::SignExtend(ManagedRegister /*mreg*/, size_t /*size*/) { - UNIMPLEMENTED(FATAL) << "no sign extension necessary for Arm64"; +void Arm64Assembler::SignExtend(ManagedRegister mreg, size_t size) { + Arm64ManagedRegister reg = mreg.AsArm64(); + CHECK(size == 1 || size == 2) << size; + CHECK(reg.IsWRegister()) << reg; + if (size == 1) { + ___ sxtb(reg_w(reg.AsWRegister()), reg_w(reg.AsWRegister())); + } else { + ___ sxth(reg_w(reg.AsWRegister()), reg_w(reg.AsWRegister())); + } } -void Arm64Assembler::ZeroExtend(ManagedRegister /*mreg*/, size_t /*size*/) { - UNIMPLEMENTED(FATAL) << "no zero extension necessary for Arm64"; +void Arm64Assembler::ZeroExtend(ManagedRegister mreg, size_t size) { + Arm64ManagedRegister reg = mreg.AsArm64(); + CHECK(size == 1 || size == 2) << size; + CHECK(reg.IsWRegister()) << reg; + if (size == 1) { + ___ uxtb(reg_w(reg.AsWRegister()), reg_w(reg.AsWRegister())); + } else { + ___ uxth(reg_w(reg.AsWRegister()), reg_w(reg.AsWRegister())); + } } void Arm64Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) { |