summaryrefslogtreecommitdiffstats
path: root/compiler/jni
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-05-01 14:38:56 -0700
committerAndreas Gampe <agampe@google.com>2014-05-01 14:55:57 -0700
commitd1104322e5156669767e8b2c3b843ffaff173381 (patch)
tree3b3e89afb1d616e958ac084a3e75c50d33deccb0 /compiler/jni
parent69cf921f5ab4467fa2c109e30ea5caca2a20790c (diff)
downloadandroid_art-d1104322e5156669767e8b2c3b843ffaff173381.tar.gz
android_art-d1104322e5156669767e8b2c3b843ffaff173381.tar.bz2
android_art-d1104322e5156669767e8b2c3b843ffaff173381.zip
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/jni')
-rw-r--r--compiler/jni/quick/arm/calling_convention_arm.h5
-rw-r--r--compiler/jni/quick/arm64/calling_convention_arm64.h5
-rw-r--r--compiler/jni/quick/calling_convention.h2
-rw-r--r--compiler/jni/quick/jni_compiler.cc2
-rw-r--r--compiler/jni/quick/mips/calling_convention_mips.h5
-rw-r--r--compiler/jni/quick/x86/calling_convention_x86.h5
-rw-r--r--compiler/jni/quick/x86_64/calling_convention_x86_64.h5
7 files changed, 28 insertions, 1 deletions
diff --git a/compiler/jni/quick/arm/calling_convention_arm.h b/compiler/jni/quick/arm/calling_convention_arm.h
index 00a239b80d..604ce1c821 100644
--- a/compiler/jni/quick/arm/calling_convention_arm.h
+++ b/compiler/jni/quick/arm/calling_convention_arm.h
@@ -71,6 +71,11 @@ class ArmJniCallingConvention FINAL : public JniCallingConvention {
ManagedRegister CurrentParamRegister() OVERRIDE;
FrameOffset CurrentParamStackOffset() OVERRIDE;
+ // AAPCS mandates return values are extended.
+ bool RequiresSmallResultTypeExtension() const OVERRIDE {
+ return false;
+ }
+
protected:
size_t NumberOfOutgoingStackArgs() OVERRIDE;
diff --git a/compiler/jni/quick/arm64/calling_convention_arm64.h b/compiler/jni/quick/arm64/calling_convention_arm64.h
index 92f547c533..9fd3265c86 100644
--- a/compiler/jni/quick/arm64/calling_convention_arm64.h
+++ b/compiler/jni/quick/arm64/calling_convention_arm64.h
@@ -68,6 +68,11 @@ class Arm64JniCallingConvention FINAL : public JniCallingConvention {
ManagedRegister CurrentParamRegister() OVERRIDE;
FrameOffset CurrentParamStackOffset() OVERRIDE;
+ // aarch64 calling convention leaves upper bits undefined.
+ bool RequiresSmallResultTypeExtension() const OVERRIDE {
+ return true;
+ }
+
protected:
size_t NumberOfOutgoingStackArgs() OVERRIDE;
diff --git a/compiler/jni/quick/calling_convention.h b/compiler/jni/quick/calling_convention.h
index 4d25d1ce96..18afd5817f 100644
--- a/compiler/jni/quick/calling_convention.h
+++ b/compiler/jni/quick/calling_convention.h
@@ -287,6 +287,8 @@ class JniCallingConvention : public CallingConvention {
FrameOffset ReturnValueSaveLocation() const;
// Register that holds result if it is integer.
virtual ManagedRegister IntReturnRegister() = 0;
+ // Whether the compiler needs to ensure zero-/sign-extension of a small result type
+ virtual bool RequiresSmallResultTypeExtension() const = 0;
// Callee save registers to spill prior to native code (which may clobber)
virtual const std::vector<ManagedRegister>& CalleeSaveRegisters() const = 0;
diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc
index 93b1b5a155..9f439eb991 100644
--- a/compiler/jni/quick/jni_compiler.cc
+++ b/compiler/jni/quick/jni_compiler.cc
@@ -314,7 +314,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver& compiler,
mr_conv->InterproceduralScratchRegister());
// 10. Fix differences in result widths.
- if (instruction_set == kX86 || instruction_set == kX86_64) {
+ if (main_jni_conv->RequiresSmallResultTypeExtension()) {
if (main_jni_conv->GetReturnType() == Primitive::kPrimByte ||
main_jni_conv->GetReturnType() == Primitive::kPrimShort) {
__ SignExtend(main_jni_conv->ReturnRegister(),
diff --git a/compiler/jni/quick/mips/calling_convention_mips.h b/compiler/jni/quick/mips/calling_convention_mips.h
index e33fbade55..8d82dceef4 100644
--- a/compiler/jni/quick/mips/calling_convention_mips.h
+++ b/compiler/jni/quick/mips/calling_convention_mips.h
@@ -71,6 +71,11 @@ class MipsJniCallingConvention FINAL : public JniCallingConvention {
ManagedRegister CurrentParamRegister() OVERRIDE;
FrameOffset CurrentParamStackOffset() OVERRIDE;
+ // Mips does not need to extend small return types.
+ bool RequiresSmallResultTypeExtension() const OVERRIDE {
+ return false;
+ }
+
protected:
size_t NumberOfOutgoingStackArgs() OVERRIDE;
diff --git a/compiler/jni/quick/x86/calling_convention_x86.h b/compiler/jni/quick/x86/calling_convention_x86.h
index 5b9069c26a..025eb6d40e 100644
--- a/compiler/jni/quick/x86/calling_convention_x86.h
+++ b/compiler/jni/quick/x86/calling_convention_x86.h
@@ -69,6 +69,11 @@ class X86JniCallingConvention FINAL : public JniCallingConvention {
ManagedRegister CurrentParamRegister() OVERRIDE;
FrameOffset CurrentParamStackOffset() OVERRIDE;
+ // x86 needs to extend small return types.
+ bool RequiresSmallResultTypeExtension() const OVERRIDE {
+ return true;
+ }
+
protected:
size_t NumberOfOutgoingStackArgs() OVERRIDE;
diff --git a/compiler/jni/quick/x86_64/calling_convention_x86_64.h b/compiler/jni/quick/x86_64/calling_convention_x86_64.h
index d545774689..1ba5353289 100644
--- a/compiler/jni/quick/x86_64/calling_convention_x86_64.h
+++ b/compiler/jni/quick/x86_64/calling_convention_x86_64.h
@@ -69,6 +69,11 @@ class X86_64JniCallingConvention FINAL : public JniCallingConvention {
ManagedRegister CurrentParamRegister() OVERRIDE;
FrameOffset CurrentParamStackOffset() OVERRIDE;
+ // x86-64 needs to extend small return types.
+ bool RequiresSmallResultTypeExtension() const OVERRIDE {
+ return true;
+ }
+
protected:
size_t NumberOfOutgoingStackArgs() OVERRIDE;