diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-06-16 14:40:02 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-06-16 14:40:02 -0700 |
commit | 7c7e2c1e2c3f2ec9e82d28494c361609042c3561 (patch) | |
tree | 4469e8fd0bbe640d669a33003b16d5c9d97a4009 /vm/compiler | |
parent | 57ea16e87e319bf71176dd8e8d12abe84f13d2e6 (diff) | |
parent | d45ba37dd5aeb6b37dd3091a4d6fa0a87f75fdf9 (diff) | |
download | android_dalvik-7c7e2c1e2c3f2ec9e82d28494c361609042c3561.tar.gz android_dalvik-7c7e2c1e2c3f2ec9e82d28494c361609042c3561.tar.bz2 android_dalvik-7c7e2c1e2c3f2ec9e82d28494c361609042c3561.zip |
Merge change 4335
* changes:
Add arm vfp support for the Jit
Diffstat (limited to 'vm/compiler')
31 files changed, 1109 insertions, 66 deletions
diff --git a/vm/compiler/codegen/armv5te/Armv5teLIR.h b/vm/compiler/codegen/armv5te/Armv5teLIR.h index 5268ee8ef..3341e496b 100644 --- a/vm/compiler/codegen/armv5te/Armv5teLIR.h +++ b/vm/compiler/codegen/armv5te/Armv5teLIR.h @@ -180,4 +180,18 @@ typedef struct Armv5teLIR { #define CHAIN_CELL_OFFSET_TAG 0xcdab +/* Create the TemplateOpcode enum */ +#define JIT_TEMPLATE(X) TEMPLATE_##X, +typedef enum { +#include "../../template/armv5te/TemplateOpList.h" +/* + * For example, + * TEMPLATE_CMP_LONG, + * TEMPLATE_RETURN, + * ... + */ + TEMPLATE_LAST_MARK, +} TemplateOpCode; +#undef JIT_TEMPLATE + #endif /* _DALVIK_VM_COMPILER_CODEGEN_ARMV5TE_H */ diff --git a/vm/compiler/codegen/armv5te/Codegen.c b/vm/compiler/codegen/armv5te/Codegen.c index 257272cb4..448a539ac 100644 --- a/vm/compiler/codegen/armv5te/Codegen.c +++ b/vm/compiler/codegen/armv5te/Codegen.c @@ -19,23 +19,10 @@ #include "libdex/OpCode.h" #include "dexdump/OpCodeNames.h" #include "vm/compiler/CompilerInternals.h" +#include "FpCodegen.h" #include "Armv5teLIR.h" #include "vm/mterp/common/FindInterface.h" -/* Create the TemplateOpcode enum */ -#define JIT_TEMPLATE(X) TEMPLATE_##X, -typedef enum { -#include "../../template/armv5te/TemplateOpList.h" -/* - * For example, - * TEMPLATE_CMP_LONG, - * TEMPLATE_RETURN, - * ... - */ - TEMPLATE_LAST_MARK, -} TemplateOpCode; -#undef JIT_TEMPLATE - /* Array holding the entry offset of each template relative to the first one */ static intptr_t templateEntryOffsets[TEMPLATE_LAST_MARK]; @@ -339,7 +326,6 @@ static void loadValueAddress(CompilationUnit *cUnit, int vSrc, int rDest) } } - /* Load a single value from rFP[src] and store them into rDest */ static void loadValue(CompilationUnit *cUnit, int vSrc, int rDest) { @@ -653,9 +639,8 @@ static bool genShiftOpLong(CompilationUnit *cUnit, MIR *mir, int vDest, storeValuePair(cUnit, r0, r1, vDest, r2); return false; } - -static bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, int vDest, - int vSrc1, int vSrc2) +bool dvmCompilerGenArithOpFloatPortable(CompilationUnit *cUnit, MIR *mir, + int vDest, int vSrc1, int vSrc2) { void* funct; /* TODO: use a proper include file to define these */ @@ -704,8 +689,8 @@ static bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, int vDest, return false; } -static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir, int vDest, - int vSrc1, int vSrc2) +bool dvmCompilerGenArithOpDoublePortable(CompilationUnit *cUnit, MIR *mir, + int vDest, int vSrc1, int vSrc2) { void* funct; /* TODO: use a proper include file to define these */ @@ -960,22 +945,22 @@ static bool genArithOp(CompilationUnit *cUnit, MIR *mir) return genArithOpInt(cUnit,mir, vA, vB, vC); } if ((opCode >= OP_ADD_FLOAT_2ADDR) && (opCode <= OP_REM_FLOAT_2ADDR)) { - return genArithOpFloat(cUnit,mir, vA, vA, vB); + return dvmCompilerGenArithOpFloat(cUnit,mir, vA, vA, vB); } if ((opCode >= OP_ADD_FLOAT) && (opCode <= OP_REM_FLOAT)) { - return genArithOpFloat(cUnit,mir, vA, vB, vC); + return dvmCompilerGenArithOpFloat(cUnit, mir, vA, vB, vC); } if ((opCode >= OP_ADD_DOUBLE_2ADDR) && (opCode <= OP_REM_DOUBLE_2ADDR)) { - return genArithOpDouble(cUnit,mir, vA, vA, vB); + return dvmCompilerGenArithOpDouble(cUnit,mir, vA, vA, vB); } if ((opCode >= OP_ADD_DOUBLE) && (opCode <= OP_REM_DOUBLE)) { - return genArithOpDouble(cUnit,mir, vA, vB, vC); + return dvmCompilerGenArithOpDouble(cUnit,mir, vA, vB, vC); } return true; } -static bool genConversion(CompilationUnit *cUnit, MIR *mir, void *funct, - int srcSize, int tgtSize) +static bool genConversionCall(CompilationUnit *cUnit, MIR *mir, void *funct, + int srcSize, int tgtSize) { loadConstant(cUnit, r2, (int)funct); if (srcSize == 1) { @@ -1475,13 +1460,10 @@ static bool handleFmt11x(CompilationUnit *cUnit, MIR *mir) return false; } -static bool handleFmt12x(CompilationUnit *cUnit, MIR *mir) +bool dvmCompilerGenConversionPortable(CompilationUnit *cUnit, MIR *mir) { OpCode opCode = mir->dalvikInsn.opCode; - int vSrc1Dest = mir->dalvikInsn.vA; - int vSrc2 = mir->dalvikInsn.vB; - /* TODO - find the proper include file to declare these */ float __aeabi_i2f( int op1 ); int __aeabi_f2iz( float op1 ); float __aeabi_d2f( double op1 ); @@ -1493,31 +1475,57 @@ static bool handleFmt12x(CompilationUnit *cUnit, MIR *mir) long __aeabi_d2lz( double op1 ); double __aeabi_l2d( long op1 ); + switch (opCode) { + case OP_INT_TO_FLOAT: + return genConversionCall(cUnit, mir, (void*)__aeabi_i2f, 1, 1); + case OP_FLOAT_TO_INT: + return genConversionCall(cUnit, mir, (void*)__aeabi_f2iz, 1, 1); + case OP_DOUBLE_TO_FLOAT: + return genConversionCall(cUnit, mir, (void*)__aeabi_d2f, 2, 1); + case OP_FLOAT_TO_DOUBLE: + return genConversionCall(cUnit, mir, (void*)__aeabi_f2d, 1, 2); + case OP_INT_TO_DOUBLE: + return genConversionCall(cUnit, mir, (void*)__aeabi_i2d, 1, 2); + case OP_DOUBLE_TO_INT: + return genConversionCall(cUnit, mir, (void*)__aeabi_d2iz, 2, 1); + case OP_FLOAT_TO_LONG: + return genConversionCall(cUnit, mir, (void*)__aeabi_f2lz, 1, 2); + case OP_LONG_TO_FLOAT: + return genConversionCall(cUnit, mir, (void*)__aeabi_l2f, 2, 1); + case OP_DOUBLE_TO_LONG: + return genConversionCall(cUnit, mir, (void*)__aeabi_d2lz, 2, 2); + case OP_LONG_TO_DOUBLE: + return genConversionCall(cUnit, mir, (void*)__aeabi_l2d, 2, 2); + default: + return true; + } + return false; +} + +static bool handleFmt12x(CompilationUnit *cUnit, MIR *mir) +{ + OpCode opCode = mir->dalvikInsn.opCode; + int vSrc1Dest = mir->dalvikInsn.vA; + int vSrc2 = mir->dalvikInsn.vB; + + /* TODO - find the proper include file to declare these */ + if ( (opCode >= OP_ADD_INT_2ADDR) && (opCode <= OP_REM_DOUBLE_2ADDR)) { return genArithOp( cUnit, mir ); } switch (opCode) { case OP_INT_TO_FLOAT: - return genConversion(cUnit, mir, (void*)__aeabi_i2f, 1, 1); case OP_FLOAT_TO_INT: - return genConversion(cUnit, mir, (void*)__aeabi_f2iz, 1, 1); case OP_DOUBLE_TO_FLOAT: - return genConversion(cUnit, mir, (void*)__aeabi_d2f, 2, 1); case OP_FLOAT_TO_DOUBLE: - return genConversion(cUnit, mir, (void*)__aeabi_f2d, 1, 2); case OP_INT_TO_DOUBLE: - return genConversion(cUnit, mir, (void*)__aeabi_i2d, 1, 2); case OP_DOUBLE_TO_INT: - return genConversion(cUnit, mir, (void*)__aeabi_d2iz, 2, 1); case OP_FLOAT_TO_LONG: - return genConversion(cUnit, mir, (void*)__aeabi_f2lz, 1, 2); case OP_LONG_TO_FLOAT: - return genConversion(cUnit, mir, (void*)__aeabi_l2f, 2, 1); case OP_DOUBLE_TO_LONG: - return genConversion(cUnit, mir, (void*)__aeabi_d2lz, 2, 2); case OP_LONG_TO_DOUBLE: - return genConversion(cUnit, mir, (void*)__aeabi_l2d, 2, 2); + return dvmCompilerGenConversion(cUnit, mir); case OP_NEG_INT: case OP_NOT_INT: return genArithOpInt(cUnit, mir, vSrc1Dest, vSrc1Dest, vSrc2); @@ -1525,9 +1533,11 @@ static bool handleFmt12x(CompilationUnit *cUnit, MIR *mir) case OP_NOT_LONG: return genArithOpLong(cUnit,mir, vSrc1Dest, vSrc1Dest, vSrc2); case OP_NEG_FLOAT: - return genArithOpFloat(cUnit,mir,vSrc1Dest,vSrc1Dest,vSrc2); + return dvmCompilerGenArithOpFloat(cUnit, mir, vSrc1Dest, + vSrc1Dest, vSrc2); case OP_NEG_DOUBLE: - return genArithOpDouble(cUnit,mir,vSrc1Dest,vSrc1Dest,vSrc2); + return dvmCompilerGenArithOpDouble(cUnit, mir, vSrc1Dest, + vSrc1Dest, vSrc2); case OP_MOVE_WIDE: loadValuePair(cUnit, mir->dalvikInsn.vB, r0, r1); storeValuePair(cUnit, r0, r1, mir->dalvikInsn.vA, r2); @@ -2036,34 +2046,15 @@ static bool handleFmt23x(CompilationUnit *cUnit, MIR *mir) } switch (opCode) { - case OP_CMP_LONG: - loadValuePair(cUnit,vB, r0, r1); - loadValuePair(cUnit, vC, r2, r3); - genDispatchToHandler(cUnit, TEMPLATE_CMP_LONG); - storeValue(cUnit, r0, vA, r1); - break; case OP_CMPL_FLOAT: - loadValue(cUnit, vB, r0); - loadValue(cUnit, vC, r1); - genDispatchToHandler(cUnit, TEMPLATE_CMPL_FLOAT); - storeValue(cUnit, r0, vA, r1); - break; case OP_CMPG_FLOAT: - loadValue(cUnit, vB, r0); - loadValue(cUnit, vC, r1); - genDispatchToHandler(cUnit, TEMPLATE_CMPG_FLOAT); - storeValue(cUnit, r0, vA, r1); - break; case OP_CMPL_DOUBLE: - loadValueAddress(cUnit, vB, r0); - loadValueAddress(cUnit, vC, r1); - genDispatchToHandler(cUnit, TEMPLATE_CMPL_DOUBLE); - storeValue(cUnit, r0, vA, r1); - break; case OP_CMPG_DOUBLE: - loadValueAddress(cUnit, vB, r0); - loadValueAddress(cUnit, vC, r1); - genDispatchToHandler(cUnit, TEMPLATE_CMPG_DOUBLE); + return dvmCompilerGenCmpX(cUnit, mir, vA, vB, vC); + case OP_CMP_LONG: + loadValuePair(cUnit,vB, r0, r1); + loadValuePair(cUnit, vC, r2, r3); + genDispatchToHandler(cUnit, TEMPLATE_CMP_LONG); storeValue(cUnit, r0, vA, r1); break; case OP_AGET_WIDE: @@ -2905,3 +2896,41 @@ void dvmCompilerArchDump(void) LOGD("dalvik.vm.jitop = %s", buf); } } + +/* + * Exported version of loadValueAddress + * TODO: revisit source file structure + */ +void dvmCompilerLoadValueAddress(CompilationUnit *cUnit, int vSrc, int rDest) +{ + loadValueAddress(cUnit, vSrc, rDest); +} + +/* + * Exported version of genDispatchToHandler + * TODO: revisit source file structure + */ +void dvmCompilerGenDispatchToHandler(CompilationUnit *cUnit, + TemplateOpCode opCode) +{ + genDispatchToHandler(cUnit, opCode); +} + +/* + * Exported version of loadValue + * TODO: revisit source file structure + */ +void dvmCompilerLoadValue(CompilationUnit *cUnit, int vSrc, int rDest) +{ + loadValue(cUnit, vSrc, rDest); +} + +/* + * Exported version of storeValue + * TODO: revisit source file structure + */ +void dvmCompilerStoreValue(CompilationUnit *cUnit, int rSrc, int vDest, + int rScratch) +{ + storeValue(cUnit, rSrc, vDest, rScratch); +} diff --git a/vm/compiler/codegen/armv5te/Codegen.h b/vm/compiler/codegen/armv5te/Codegen.h new file mode 100644 index 000000000..f156e600e --- /dev/null +++ b/vm/compiler/codegen/armv5te/Codegen.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Dalvik.h" +#include "compiler/CompilerInternals.h" +#include "Armv5teLIR.h" + +#ifndef _DALVIK_VM_COMPILER_CODEGEN_CODEGEN_H +#define _DALVIK_VM_COMPILER_CODEGEN_CODEGEN_H + +bool dvmCompilerGenConversionPortable(CompilationUnit *cUnit, MIR *mir); +bool dvmCompilerGenArithOpFloatPortable(CompilationUnit *cUnit, MIR *mir, + int vDest, int vSrc1, int vSrc2); +bool dvmCompilerGenArithOpDoublePortable(CompilationUnit *cUnit, MIR *mir, + int vDest, int vSrc1, int vSrc2); +void dvmCompilerLoadValueAddress(CompilationUnit *cUnit, int vSrc, int rDest); +void dvmCompilerGenDispatchToHandler(CompilationUnit *cUnit, + TemplateOpCode opCode); +void dvmCompilerLoadValue(CompilationUnit *cUnit, int vSrc, int rDest); +void dvmCompilerStoreValue(CompilationUnit *cUnit, int rSrc, int vDest, + int rScratch); + +#endif /* _DALVIK_VM_COMPILER_CODEGEN_CODEGEN_H */ diff --git a/vm/compiler/codegen/armv5te/FpCodegen-armv5te-vfp.c b/vm/compiler/codegen/armv5te/FpCodegen-armv5te-vfp.c new file mode 100644 index 000000000..7e483c868 --- /dev/null +++ b/vm/compiler/codegen/armv5te/FpCodegen-armv5te-vfp.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Dalvik.h" +#include "Armv5teLIR.h" +#include "Codegen.h" + +bool dvmCompilerGenArithOpFloat(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2) +{ + TemplateOpCode opCode; + + switch (mir->dalvikInsn.opCode) { + case OP_ADD_FLOAT_2ADDR: + case OP_ADD_FLOAT: + opCode = TEMPLATE_ADD_FLOAT_VFP; + break; + case OP_SUB_FLOAT_2ADDR: + case OP_SUB_FLOAT: + opCode = TEMPLATE_SUB_FLOAT_VFP; + case OP_DIV_FLOAT_2ADDR: + case OP_DIV_FLOAT: + opCode = TEMPLATE_DIV_FLOAT_VFP; + break; + case OP_MUL_FLOAT_2ADDR: + case OP_MUL_FLOAT: + opCode = TEMPLATE_MUL_FLOAT_VFP; + break; + case OP_REM_FLOAT_2ADDR: + case OP_REM_FLOAT: + case OP_NEG_FLOAT: { + return dvmCompilerGenArithOpFloatPortable(cUnit, mir, vDest, + vSrc1, vSrc2); + } + default: + return true; + } + dvmCompilerLoadValueAddress(cUnit, vDest, r0); + dvmCompilerLoadValueAddress(cUnit, vSrc1, r1); + dvmCompilerLoadValueAddress(cUnit, vSrc2, r2); + dvmCompilerGenDispatchToHandler(cUnit, opCode); + return false; +} + +bool dvmCompilerGenArithOpDouble(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2) +{ + TemplateOpCode opCode; + + switch (mir->dalvikInsn.opCode) { + case OP_ADD_DOUBLE_2ADDR: + case OP_ADD_DOUBLE: + opCode = TEMPLATE_ADD_DOUBLE_VFP; + break; + case OP_SUB_DOUBLE_2ADDR: + case OP_SUB_DOUBLE: + opCode = TEMPLATE_SUB_DOUBLE_VFP; + break; + case OP_DIV_DOUBLE_2ADDR: + case OP_DIV_DOUBLE: + opCode = TEMPLATE_DIV_DOUBLE_VFP; + break; + case OP_MUL_DOUBLE_2ADDR: + case OP_MUL_DOUBLE: + opCode = TEMPLATE_MUL_DOUBLE_VFP; + break; + case OP_REM_DOUBLE_2ADDR: + case OP_REM_DOUBLE: + case OP_NEG_DOUBLE: { + return dvmCompilerGenArithOpDoublePortable(cUnit, mir, vDest, + vSrc1, vSrc2); + } + default: + return true; + } + dvmCompilerLoadValueAddress(cUnit, vDest, r0); + dvmCompilerLoadValueAddress(cUnit, vSrc1, r1); + dvmCompilerLoadValueAddress(cUnit, vSrc2, r2); + dvmCompilerGenDispatchToHandler(cUnit, opCode); + return false; +} + +bool dvmCompilerGenConversion(CompilationUnit *cUnit, MIR *mir) +{ + OpCode opCode = mir->dalvikInsn.opCode; + int vSrc1Dest = mir->dalvikInsn.vA; + int vSrc2 = mir->dalvikInsn.vB; + TemplateOpCode template; + + switch (opCode) { + case OP_INT_TO_FLOAT: + template = TEMPLATE_INT_TO_FLOAT_VFP; + break; + case OP_FLOAT_TO_INT: + template = TEMPLATE_FLOAT_TO_INT_VFP; + break; + case OP_DOUBLE_TO_FLOAT: + template = TEMPLATE_DOUBLE_TO_FLOAT_VFP; + break; + case OP_FLOAT_TO_DOUBLE: + template = TEMPLATE_FLOAT_TO_DOUBLE_VFP; + break; + case OP_INT_TO_DOUBLE: + template = TEMPLATE_INT_TO_DOUBLE_VFP; + break; + case OP_DOUBLE_TO_INT: + template = TEMPLATE_DOUBLE_TO_INT_VFP; + break; + case OP_FLOAT_TO_LONG: + case OP_LONG_TO_FLOAT: + case OP_DOUBLE_TO_LONG: + case OP_LONG_TO_DOUBLE: + return dvmCompilerGenConversionPortable(cUnit, mir); + default: + return true; + } + dvmCompilerLoadValueAddress(cUnit, vSrc1Dest, r0); + dvmCompilerLoadValueAddress(cUnit, vSrc2, r1); + dvmCompilerGenDispatchToHandler(cUnit, template); + return false; +} + +bool dvmCompilerGenCmpX(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2) +{ + TemplateOpCode template; + switch(mir->dalvikInsn.opCode) { + case OP_CMPL_FLOAT: + template = TEMPLATE_CMPL_FLOAT_VFP; + break; + case OP_CMPG_FLOAT: + template = TEMPLATE_CMPG_FLOAT_VFP; + break; + case OP_CMPL_DOUBLE: + template = TEMPLATE_CMPL_DOUBLE_VFP; + break; + case OP_CMPG_DOUBLE: + template = TEMPLATE_CMPG_DOUBLE_VFP; + break; + default: + return true; + } + dvmCompilerLoadValueAddress(cUnit, vSrc1, r0); + dvmCompilerLoadValueAddress(cUnit, vSrc2, r1); + dvmCompilerGenDispatchToHandler(cUnit, template); + dvmCompilerStoreValue(cUnit, r0, vDest, r1); + return false; +} diff --git a/vm/compiler/codegen/armv5te/FpCodegen-armv5te.c b/vm/compiler/codegen/armv5te/FpCodegen-armv5te.c new file mode 100644 index 000000000..26a40bcf9 --- /dev/null +++ b/vm/compiler/codegen/armv5te/FpCodegen-armv5te.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Dalvik.h" +#include "Armv5teLIR.h" +#include "Codegen.h" + +bool dvmCompilerGenConversion(CompilationUnit *cUnit, MIR *mir) +{ + return dvmCompilerGenConversionPortable(cUnit, mir); +} + +bool dvmCompilerGenArithOpFloat(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2) +{ + return dvmCompilerGenArithOpFloatPortable(cUnit, mir, vDest, vSrc1, vSrc2); +} + +bool dvmCompilerGenArithOpDouble(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2) +{ + return dvmCompilerGenArithOpDoublePortable(cUnit, mir, vDest, vSrc1, vSrc2); +} + +bool dvmCompilerGenCmpX(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2) +{ + switch (mir->dalvikInsn.opCode) { + case OP_CMPL_FLOAT: + dvmCompilerLoadValue(cUnit, vSrc1, r0); + dvmCompilerLoadValue(cUnit, vSrc2, r1); + dvmCompilerGenDispatchToHandler(cUnit, TEMPLATE_CMPL_FLOAT); + dvmCompilerStoreValue(cUnit, r0, vDest, r1); + break; + case OP_CMPG_FLOAT: + dvmCompilerLoadValue(cUnit, vSrc1, r0); + dvmCompilerLoadValue(cUnit, vSrc2, r1); + dvmCompilerGenDispatchToHandler(cUnit, TEMPLATE_CMPG_FLOAT); + dvmCompilerStoreValue(cUnit, r0, vDest, r1); + break; + case OP_CMPL_DOUBLE: + dvmCompilerLoadValueAddress(cUnit, vSrc1, r0); + dvmCompilerLoadValueAddress(cUnit, vSrc2, r1); + dvmCompilerGenDispatchToHandler(cUnit, TEMPLATE_CMPL_DOUBLE); + dvmCompilerStoreValue(cUnit, r0, vDest, r1); + break; + case OP_CMPG_DOUBLE: + dvmCompilerLoadValueAddress(cUnit, vSrc1, r0); + dvmCompilerLoadValueAddress(cUnit, vSrc2, r1); + dvmCompilerGenDispatchToHandler(cUnit, TEMPLATE_CMPG_DOUBLE); + dvmCompilerStoreValue(cUnit, r0, vDest, r1); + break; + default: + return true; + } + return false; +} diff --git a/vm/compiler/codegen/armv5te/FpCodegen.h b/vm/compiler/codegen/armv5te/FpCodegen.h new file mode 100644 index 000000000..72625b53f --- /dev/null +++ b/vm/compiler/codegen/armv5te/FpCodegen.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Dalvik.h" +#include "compiler/CompilerInternals.h" + +#ifndef _DALVIK_VM_COMPILER_CODEGEN_FPCODEGEN_H +#define _DALVIK_VM_COMPILER_CODEGEN_FPCODEGEN_H + +bool dvmCompilerGenConversion(CompilationUnit *cUnit, MIR *mir); +bool dvmCompilerGenArithOpFloat(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2); +bool dvmCompilerGenArithOpDouble(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2); +bool dvmCompilerGenCmpX(CompilationUnit *cUnit, MIR *mir, int vDest, + int vSrc1, int vSrc2); + + +#endif /* _DALVIK_VM_COMPILER_CODEGEN_FPCODEGEN_H */ diff --git a/vm/compiler/template/armv5te/TEMPLATE_ADD_DOUBLE_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_ADD_DOUBLE_VFP.S new file mode 100644 index 000000000..7b4fa0153 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_ADD_DOUBLE_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/fbinopWide.S" {"instr":"faddd d2, d0, d1"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_ADD_FLOAT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_ADD_FLOAT_VFP.S new file mode 100644 index 000000000..6e8077c24 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_ADD_FLOAT_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/fbinop.S" {"instr":"fadds s2, s0, s1"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_CMPG_DOUBLE_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_CMPG_DOUBLE_VFP.S new file mode 100644 index 000000000..3801f49b7 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_CMPG_DOUBLE_VFP.S @@ -0,0 +1,34 @@ +%verify "executed" +%verify "basic lt, gt, eq */ +%verify "left arg NaN" +%verify "right arg NaN" + /* + * Compare two floating-point values. Puts 0, 1, or -1 into the + * destination register based on the results of the comparison. + * + * int compare(x, y) { + * if (x == y) { + * return 0; + * } else if (x < y) { + * return -1; + * } else if (x > y) { + * return 1; + * } else { + * return 1; + * } + * } + * + * On entry: + * r0 = &op1 [vBB] + * r1 = &op2 [vCC] + */ + /* op vAA, vBB, vCC */ + fldd d0, [r0] @ d0<- vBB + fldd d1, [r1] @ d1<- vCC + fcmped d0, d1 @ compare (vBB, vCC) + mov r0, #1 @ r0<- 1 (default) + fmstat @ export status flags + mvnmi r0, #0 @ (less than) r0<- -1 + moveq r0, #0 @ (equal) r0<- 0 + bx lr + diff --git a/vm/compiler/template/armv5te/TEMPLATE_CMPG_FLOAT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_CMPG_FLOAT_VFP.S new file mode 100644 index 000000000..1faafa1a1 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_CMPG_FLOAT_VFP.S @@ -0,0 +1,32 @@ +%verify "executed" +%verify "basic lt, gt, eq */ +%verify "left arg NaN" +%verify "right arg NaN" + /* + * Compare two floating-point values. Puts 0, 1, or -1 into the + * destination register based on the results of the comparison. + * + * int compare(x, y) { + * if (x == y) { + * return 0; + * } else if (x < y) { + * return -1; + * } else if (x > y) { + * return 1; + * } else { + * return 1; + * } + * } + * On entry: + * r0 = &op1 [vBB] + * r1 = &op2 [vCC] + */ + /* op vAA, vBB, vCC */ + flds s0, [r0] @ d0<- vBB + flds s1, [r1] @ d1<- vCC + fcmpes s0, s1 @ compare (vBB, vCC) + mov r0, #1 @ r0<- 1 (default) + fmstat @ export status flags + mvnmi r0, #0 @ (less than) r0<- -1 + moveq r0, #0 @ (equal) r0<- 0 + bx lr diff --git a/vm/compiler/template/armv5te/TEMPLATE_CMPL_DOUBLE_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_CMPL_DOUBLE_VFP.S new file mode 100644 index 000000000..7241af14e --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_CMPL_DOUBLE_VFP.S @@ -0,0 +1,32 @@ +%verify "executed" +%verify "basic lt, gt, eq */ +%verify "left arg NaN" +%verify "right arg NaN" + /* + * Compare two floating-point values. Puts 0, 1, or -1 into the + * destination register based on the results of the comparison. + * + * int compare(x, y) { + * if (x == y) { + * return 0; + * } else if (x > y) { + * return 1; + * } else if (x < y) { + * return -1; + * } else { + * return -1; + * } + * } + * On entry: + * r0 = &op1 [vBB] + * r1 = &op2 [vCC] + */ + /* op vAA, vBB, vCC */ + fldd d0, [r0] @ d0<- vBB + fldd d1, [r1] @ d1<- vCC + fcmped d0, d1 @ compare (vBB, vCC) + mvn r0, #0 @ r0<- -1 (default) + fmstat @ export status flags + movgt r0, #1 @ (greater than) r0<- 1 + moveq r0, #0 @ (equal) r0<- 0 + bx lr diff --git a/vm/compiler/template/armv5te/TEMPLATE_CMPL_FLOAT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_CMPL_FLOAT_VFP.S new file mode 100644 index 000000000..014f160ae --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_CMPL_FLOAT_VFP.S @@ -0,0 +1,32 @@ +%verify "executed" +%verify "basic lt, gt, eq */ +%verify "left arg NaN" +%verify "right arg NaN" + /* + * Compare two floating-point values. Puts 0, 1, or -1 into the + * destination register based on the results of the comparison. + * + * int compare(x, y) { + * if (x == y) { + * return 0; + * } else if (x > y) { + * return 1; + * } else if (x < y) { + * return -1; + * } else { + * return -1; + * } + * } + * On entry: + * r0 = &op1 [vBB] + * r1 = &op2 [vCC] + */ + /* op vAA, vBB, vCC */ + flds s0, [r0] @ d0<- vBB + flds s1, [r1] @ d1<- vCC + fcmpes s0, s1 @ compare (vBB, vCC) + mvn r0, #0 @ r0<- -1 (default) + fmstat @ export status flags + movgt r0, #1 @ (greater than) r0<- 1 + moveq r0, #0 @ (equal) r0<- 0 + bx lr diff --git a/vm/compiler/template/armv5te/TEMPLATE_DIV_DOUBLE_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_DIV_DOUBLE_VFP.S new file mode 100644 index 000000000..796275a0a --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_DIV_DOUBLE_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/fbinopWide.S" {"instr":"fdivd d2, d0, d1"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_DIV_FLOAT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_DIV_FLOAT_VFP.S new file mode 100644 index 000000000..5895b93b7 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_DIV_FLOAT_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/fbinop.S" {"instr":"fdivs s2, s0, s1"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_DOUBLE_TO_FLOAT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_DOUBLE_TO_FLOAT_VFP.S new file mode 100644 index 000000000..96f50c7fc --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_DOUBLE_TO_FLOAT_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/funopNarrower.S" {"instr":"fcvtsd s0, d0"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_DOUBLE_TO_INT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_DOUBLE_TO_INT_VFP.S new file mode 100644 index 000000000..f6353836c --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_DOUBLE_TO_INT_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/funopNarrower.S" {"instr":"ftosizd s0, d0"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_FLOAT_TO_DOUBLE_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_FLOAT_TO_DOUBLE_VFP.S new file mode 100644 index 000000000..a2d68bde5 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_FLOAT_TO_DOUBLE_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/funopWider.S" {"instr":"fcvtds d0, s0"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_FLOAT_TO_INT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_FLOAT_TO_INT_VFP.S new file mode 100644 index 000000000..bebff4389 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_FLOAT_TO_INT_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/funop.S" {"instr":"ftosizs s1, s0"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_INT_TO_DOUBLE_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_INT_TO_DOUBLE_VFP.S new file mode 100644 index 000000000..0a987ac5e --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_INT_TO_DOUBLE_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/funopWider.S" {"instr":"fsitod d0, s0"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_INT_TO_FLOAT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_INT_TO_FLOAT_VFP.S new file mode 100644 index 000000000..105a4a42d --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_INT_TO_FLOAT_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/funop.S" {"instr":"fsitos s1, s0"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_MUL_DOUBLE_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_MUL_DOUBLE_VFP.S new file mode 100644 index 000000000..f9afa213c --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_MUL_DOUBLE_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/fbinopWide.S" {"instr":"fmuld d2, d0, d1"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_MUL_FLOAT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_MUL_FLOAT_VFP.S new file mode 100644 index 000000000..066680328 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_MUL_FLOAT_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/fbinop.S" {"instr":"fmuls s2, s0, s1"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_SUB_DOUBLE_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_SUB_DOUBLE_VFP.S new file mode 100644 index 000000000..0c3dd4e0e --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_SUB_DOUBLE_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/fbinopWide.S" {"instr":"fsubd d2, d0, d1"} diff --git a/vm/compiler/template/armv5te/TEMPLATE_SUB_FLOAT_VFP.S b/vm/compiler/template/armv5te/TEMPLATE_SUB_FLOAT_VFP.S new file mode 100644 index 000000000..b7bb5b875 --- /dev/null +++ b/vm/compiler/template/armv5te/TEMPLATE_SUB_FLOAT_VFP.S @@ -0,0 +1,2 @@ +%verify "executed" +%include "armv5te/fbinop.S" {"instr":"fsubs s2, s0, s1"} diff --git a/vm/compiler/template/armv5te/TemplateOpList.h b/vm/compiler/template/armv5te/TemplateOpList.h index 6428ccf12..f41900e6a 100644 --- a/vm/compiler/template/armv5te/TemplateOpList.h +++ b/vm/compiler/template/armv5te/TemplateOpList.h @@ -33,3 +33,21 @@ JIT_TEMPLATE(MUL_LONG) JIT_TEMPLATE(SHL_LONG) JIT_TEMPLATE(SHR_LONG) JIT_TEMPLATE(USHR_LONG) +JIT_TEMPLATE(ADD_FLOAT_VFP) +JIT_TEMPLATE(SUB_FLOAT_VFP) +JIT_TEMPLATE(MUL_FLOAT_VFP) +JIT_TEMPLATE(DIV_FLOAT_VFP) +JIT_TEMPLATE(ADD_DOUBLE_VFP) +JIT_TEMPLATE(SUB_DOUBLE_VFP) +JIT_TEMPLATE(MUL_DOUBLE_VFP) +JIT_TEMPLATE(DIV_DOUBLE_VFP) +JIT_TEMPLATE(DOUBLE_TO_FLOAT_VFP) +JIT_TEMPLATE(DOUBLE_TO_INT_VFP) +JIT_TEMPLATE(FLOAT_TO_DOUBLE_VFP) +JIT_TEMPLATE(FLOAT_TO_INT_VFP) +JIT_TEMPLATE(INT_TO_DOUBLE_VFP) +JIT_TEMPLATE(INT_TO_FLOAT_VFP) +JIT_TEMPLATE(CMPG_DOUBLE_VFP) +JIT_TEMPLATE(CMPL_DOUBLE_VFP) +JIT_TEMPLATE(CMPG_FLOAT_VFP) +JIT_TEMPLATE(CMPL_FLOAT_VFP) diff --git a/vm/compiler/template/armv5te/fbinop.S b/vm/compiler/template/armv5te/fbinop.S new file mode 100644 index 000000000..3bc4b52a9 --- /dev/null +++ b/vm/compiler/template/armv5te/fbinop.S @@ -0,0 +1,14 @@ + /* + * Generic 32-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + flds s0,[r1] + flds s1,[r2] + $instr + fsts s2,[r0] + bx lr diff --git a/vm/compiler/template/armv5te/fbinopWide.S b/vm/compiler/template/armv5te/fbinopWide.S new file mode 100644 index 000000000..3774646bf --- /dev/null +++ b/vm/compiler/template/armv5te/fbinopWide.S @@ -0,0 +1,14 @@ + /* + * Generic 64-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + fldd d0,[r1] + fldd d1,[r2] + $instr + fstd d2,[r0] + bx lr diff --git a/vm/compiler/template/armv5te/funop.S b/vm/compiler/template/armv5te/funop.S new file mode 100644 index 000000000..8409c287c --- /dev/null +++ b/vm/compiler/template/armv5te/funop.S @@ -0,0 +1,15 @@ + /* + * Generic 32bit-to-32bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "s1 = op s0". + * + * For: float-to-int, int-to-float + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + flds s0, [r1] @ s0<- vB + $instr @ s1<- op s0 + fsts s1, [r0] @ vA<- s1 + bx lr diff --git a/vm/compiler/template/armv5te/funopNarrower.S b/vm/compiler/template/armv5te/funopNarrower.S new file mode 100644 index 000000000..8566fcaf2 --- /dev/null +++ b/vm/compiler/template/armv5te/funopNarrower.S @@ -0,0 +1,15 @@ + /* + * Generic 64bit-to-32bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "s0 = op d0". + * + * For: double-to-int, double-to-float + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + fldd d0, [r1] @ d0<- vB + $instr @ s0<- op d0 + fsts s0, [r0] @ vA<- s0 + bx lr diff --git a/vm/compiler/template/armv5te/funopWider.S b/vm/compiler/template/armv5te/funopWider.S new file mode 100644 index 000000000..dbe745c9b --- /dev/null +++ b/vm/compiler/template/armv5te/funopWider.S @@ -0,0 +1,15 @@ + /* + * Generic 32bit-to-64bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "d0 = op s0". + * + * For: int-to-double, float-to-double + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + flds s0, [r1] @ s0<- vB + $instr @ d0<- op s0 + fstd d0, [r0] @ vA<- d0 + bx lr diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S b/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S index a38c613e0..adafb4828 100644 --- a/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S +++ b/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S @@ -640,6 +640,458 @@ dvmCompiler_TEMPLATE_USHR_LONG: bx lr +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_ADD_FLOAT_VFP +dvmCompiler_TEMPLATE_ADD_FLOAT_VFP: +/* File: armv5te/TEMPLATE_ADD_FLOAT_VFP.S */ +/* File: armv5te/fbinop.S */ + /* + * Generic 32-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + flds s0,[r1] + flds s1,[r2] + fadds s2, s0, s1 + fsts s2,[r0] + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_SUB_FLOAT_VFP +dvmCompiler_TEMPLATE_SUB_FLOAT_VFP: +/* File: armv5te/TEMPLATE_SUB_FLOAT_VFP.S */ +/* File: armv5te/fbinop.S */ + /* + * Generic 32-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + flds s0,[r1] + flds s1,[r2] + fsubs s2, s0, s1 + fsts s2,[r0] + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_MUL_FLOAT_VFP +dvmCompiler_TEMPLATE_MUL_FLOAT_VFP: +/* File: armv5te/TEMPLATE_MUL_FLOAT_VFP.S */ +/* File: armv5te/fbinop.S */ + /* + * Generic 32-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + flds s0,[r1] + flds s1,[r2] + fmuls s2, s0, s1 + fsts s2,[r0] + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_DIV_FLOAT_VFP +dvmCompiler_TEMPLATE_DIV_FLOAT_VFP: +/* File: armv5te/TEMPLATE_DIV_FLOAT_VFP.S */ +/* File: armv5te/fbinop.S */ + /* + * Generic 32-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + flds s0,[r1] + flds s1,[r2] + fdivs s2, s0, s1 + fsts s2,[r0] + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_ADD_DOUBLE_VFP +dvmCompiler_TEMPLATE_ADD_DOUBLE_VFP: +/* File: armv5te/TEMPLATE_ADD_DOUBLE_VFP.S */ +/* File: armv5te/fbinopWide.S */ + /* + * Generic 64-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + fldd d0,[r1] + fldd d1,[r2] + faddd d2, d0, d1 + fstd d2,[r0] + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_SUB_DOUBLE_VFP +dvmCompiler_TEMPLATE_SUB_DOUBLE_VFP: +/* File: armv5te/TEMPLATE_SUB_DOUBLE_VFP.S */ +/* File: armv5te/fbinopWide.S */ + /* + * Generic 64-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + fldd d0,[r1] + fldd d1,[r2] + fsubd d2, d0, d1 + fstd d2,[r0] + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_MUL_DOUBLE_VFP +dvmCompiler_TEMPLATE_MUL_DOUBLE_VFP: +/* File: armv5te/TEMPLATE_MUL_DOUBLE_VFP.S */ +/* File: armv5te/fbinopWide.S */ + /* + * Generic 64-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + fldd d0,[r1] + fldd d1,[r2] + fmuld d2, d0, d1 + fstd d2,[r0] + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_DIV_DOUBLE_VFP +dvmCompiler_TEMPLATE_DIV_DOUBLE_VFP: +/* File: armv5te/TEMPLATE_DIV_DOUBLE_VFP.S */ +/* File: armv5te/fbinopWide.S */ + /* + * Generic 64-bit floating point operation. Provide an "instr" line that + * specifies an instruction that performs s2 = s0 op s1. + * + * On entry: + * r0 = target dalvik register address + * r1 = op1 address + * r2 = op2 address + */ + fldd d0,[r1] + fldd d1,[r2] + fdivd d2, d0, d1 + fstd d2,[r0] + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_DOUBLE_TO_FLOAT_VFP +dvmCompiler_TEMPLATE_DOUBLE_TO_FLOAT_VFP: +/* File: armv5te/TEMPLATE_DOUBLE_TO_FLOAT_VFP.S */ +/* File: armv5te/funopNarrower.S */ + /* + * Generic 64bit-to-32bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "s0 = op d0". + * + * For: double-to-int, double-to-float + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + fldd d0, [r1] @ d0<- vB + fcvtsd s0, d0 @ s0<- op d0 + fsts s0, [r0] @ vA<- s0 + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_DOUBLE_TO_INT_VFP +dvmCompiler_TEMPLATE_DOUBLE_TO_INT_VFP: +/* File: armv5te/TEMPLATE_DOUBLE_TO_INT_VFP.S */ +/* File: armv5te/funopNarrower.S */ + /* + * Generic 64bit-to-32bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "s0 = op d0". + * + * For: double-to-int, double-to-float + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + fldd d0, [r1] @ d0<- vB + ftosizd s0, d0 @ s0<- op d0 + fsts s0, [r0] @ vA<- s0 + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_FLOAT_TO_DOUBLE_VFP +dvmCompiler_TEMPLATE_FLOAT_TO_DOUBLE_VFP: +/* File: armv5te/TEMPLATE_FLOAT_TO_DOUBLE_VFP.S */ +/* File: armv5te/funopWider.S */ + /* + * Generic 32bit-to-64bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "d0 = op s0". + * + * For: int-to-double, float-to-double + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + flds s0, [r1] @ s0<- vB + fcvtds d0, s0 @ d0<- op s0 + fstd d0, [r0] @ vA<- d0 + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_FLOAT_TO_INT_VFP +dvmCompiler_TEMPLATE_FLOAT_TO_INT_VFP: +/* File: armv5te/TEMPLATE_FLOAT_TO_INT_VFP.S */ +/* File: armv5te/funop.S */ + /* + * Generic 32bit-to-32bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "s1 = op s0". + * + * For: flot-to-int, int-to-float + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + flds s0, [r1] @ s0<- vB + ftosizs s1, s0 @ s1<- op s0 + fsts s1, [r0] @ vA<- s1 + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_INT_TO_DOUBLE_VFP +dvmCompiler_TEMPLATE_INT_TO_DOUBLE_VFP: +/* File: armv5te/TEMPLATE_INT_TO_DOUBLE_VFP.S */ +/* File: armv5te/funopWider.S */ + /* + * Generic 32bit-to-64bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "d0 = op s0". + * + * For: int-to-double, float-to-double + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + flds s0, [r1] @ s0<- vB + fsitod d0, s0 @ d0<- op s0 + fstd d0, [r0] @ vA<- d0 + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_INT_TO_FLOAT_VFP +dvmCompiler_TEMPLATE_INT_TO_FLOAT_VFP: +/* File: armv5te/TEMPLATE_INT_TO_FLOAT_VFP.S */ +/* File: armv5te/funop.S */ + /* + * Generic 32bit-to-32bit floating point unary operation. Provide an + * "instr" line that specifies an instruction that performs "s1 = op s0". + * + * For: flot-to-int, int-to-float + * + * On entry: + * r0 = target dalvik register address + * r1 = src dalvik register address + */ + /* unop vA, vB */ + flds s0, [r1] @ s0<- vB + fsitos s1, s0 @ s1<- op s0 + fsts s1, [r0] @ vA<- s1 + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_CMPG_DOUBLE_VFP +dvmCompiler_TEMPLATE_CMPG_DOUBLE_VFP: +/* File: armv5te/TEMPLATE_CMPG_DOUBLE_VFP.S */ + /* + * Compare two floating-point values. Puts 0, 1, or -1 into the + * destination register based on the results of the comparison. + * + * int compare(x, y) { + * if (x == y) { + * return 0; + * } else if (x < y) { + * return -1; + * } else if (x > y) { + * return 1; + * } else { + * return 1; + * } + * } + * + * On entry: + * r0 = &op1 [vBB] + * r1 = &op2 [vCC] + */ + /* op vAA, vBB, vCC */ + fldd d0, [r0] @ d0<- vBB + fldd d1, [r1] @ d1<- vCC + fcmped d0, d1 @ compare (vBB, vCC) + mov r0, #1 @ r0<- 1 (default) + fmstat @ export status flags + mvnmi r0, #0 @ (less than) r0<- -1 + moveq r0, #0 @ (equal) r0<- 0 + bx lr + + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_CMPL_DOUBLE_VFP +dvmCompiler_TEMPLATE_CMPL_DOUBLE_VFP: +/* File: armv5te/TEMPLATE_CMPL_DOUBLE_VFP.S */ + /* + * Compare two floating-point values. Puts 0, 1, or -1 into the + * destination register based on the results of the comparison. + * + * int compare(x, y) { + * if (x == y) { + * return 0; + * } else if (x > y) { + * return 1; + * } else if (x < y) { + * return -1; + * } else { + * return -1; + * } + * } + * On entry: + * r0 = &op1 [vBB] + * r1 = &op2 [vCC] + */ + /* op vAA, vBB, vCC */ + fldd d0, [r0] @ d0<- vBB + fldd d1, [r1] @ d1<- vCC + fcmped d0, d1 @ compare (vBB, vCC) + mvn r0, #0 @ r0<- -1 (default) + fmstat @ export status flags + movgt r0, #1 @ (greater than) r0<- 1 + moveq r0, #0 @ (equal) r0<- 0 + bx lr + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_CMPG_FLOAT_VFP +dvmCompiler_TEMPLATE_CMPG_FLOAT_VFP: +/* File: armv5te/TEMPLATE_CMPG_FLOAT_VFP.S */ + /* + * Compare two floating-point values. Puts 0, 1, or -1 into the + * destination register based on the results of the comparison. + * + * int compare(x, y) { + * if (x == y) { + * return 0; + * } else if (x < y) { + * return -1; + * } else if (x > y) { + * return 1; + * } else { + * return 1; + * } + * } + * On entry: + * r0 = &op1 [vBB] + * r1 = &op2 [vCC] + */ + /* op vAA, vBB, vCC */ + flds s0, [r0] @ d0<- vBB + flds s1, [r1] @ d1<- vCC + fcmpes s0, s1 @ compare (vBB, vCC) + mov r0, #1 @ r0<- 1 (default) + fmstat @ export status flags + mvnmi r0, #0 @ (less than) r0<- -1 + moveq r0, #0 @ (equal) r0<- 0 + bx lr + +/* ------------------------------ */ + .balign 4 + .global dvmCompiler_TEMPLATE_CMPL_FLOAT_VFP +dvmCompiler_TEMPLATE_CMPL_FLOAT_VFP: +/* File: armv5te/TEMPLATE_CMPL_FLOAT_VFP.S */ + /* + * Compare two floating-point values. Puts 0, 1, or -1 into the + * destination register based on the results of the comparison. + * + * int compare(x, y) { + * if (x == y) { + * return 0; + * } else if (x > y) { + * return 1; + * } else if (x < y) { + * return -1; + * } else { + * return -1; + * } + * } + * On entry: + * r0 = &op1 [vBB] + * r1 = &op2 [vCC] + */ + /* op vAA, vBB, vCC */ + flds s0, [r0] @ d0<- vBB + flds s1, [r1] @ d1<- vCC + fcmpes s0, s1 @ compare (vBB, vCC) + mvn r0, #0 @ r0<- -1 (default) + fmstat @ export status flags + movgt r0, #1 @ (greater than) r0<- 1 + moveq r0, #0 @ (equal) r0<- 0 + bx lr + .size dvmCompilerTemplateStart, .-dvmCompilerTemplateStart /* File: armv5te/footer.S */ /* |