From b6545ac7541847ab455339592c9d38165d071504 Mon Sep 17 00:00:00 2001 From: knn-k Date: Tue, 11 Dec 2018 17:45:34 +0900 Subject: [PATCH] AArch64: Implement FP type conversion evaluators This commit implements type conversion evaluators of floating-point types, such as i2f, d2l, and f2d. Signed-off-by: knn-k --- compiler/aarch64/codegen/ARM64Debug.cpp | 12 +++ compiler/aarch64/codegen/FPTreeEvaluator.cpp | 94 +++++++++++-------- .../aarch64/codegen/OMRInstOpCodeEnum.hpp | 12 +++ compiler/aarch64/codegen/OpBinary.cpp | 12 +++ .../aarch64/codegen/TreeEvaluatorTable.hpp | 20 ++-- 5 files changed, 100 insertions(+), 50 deletions(-) diff --git a/compiler/aarch64/codegen/ARM64Debug.cpp b/compiler/aarch64/codegen/ARM64Debug.cpp index b362f32073b..06f4998bd54 100644 --- a/compiler/aarch64/codegen/ARM64Debug.cpp +++ b/compiler/aarch64/codegen/ARM64Debug.cpp @@ -437,8 +437,20 @@ static const char *opCodeToNameMap[] = "rev32", "fmovs", "fmovd", + "fmov_stow", "fmov_wtos", + "fmov_dtox", "fmov_xtod", + "fcvt_stod", + "fcvt_dtos", + "fcvtzs_stow", + "fcvtzs_dtow", + "fcvtzs_stox", + "fcvtzs_dtox", + "scvtf_wtos", + "scvtf_wtod", + "scvtf_xtos", + "scvtf_xtod", "proc", "fence", "return", diff --git a/compiler/aarch64/codegen/FPTreeEvaluator.cpp b/compiler/aarch64/codegen/FPTreeEvaluator.cpp index 992ccb62337..7a64764e87c 100644 --- a/compiler/aarch64/codegen/FPTreeEvaluator.cpp +++ b/compiler/aarch64/codegen/FPTreeEvaluator.cpp @@ -227,54 +227,71 @@ OMR::ARM64::TreeEvaluator::dnegEvaluator(TR::Node *node, TR::CodeGenerator *cg) return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); } +static TR::Register * +intFpTypeCoversionHelper(TR::Node *node, TR::InstOpCode::Mnemonic op, TR::CodeGenerator *cg) + { + TR::Node *child = node->getFirstChild(); + TR::Register *srcReg = cg->evaluate(child); + TR::Register *trgReg; + + TR::DataType dt = node->getDataType(); + if (dt.isFloatingPoint()) + { + trgReg = dt.isDouble() ? cg->allocateRegister(TR_FPR) : cg->allocateSinglePrecisionRegister(); + } + else + { + trgReg = cg->allocateRegister(); + } + + generateTrg1Src1Instruction(cg, op, node, trgReg, srcReg); + + child->decReferenceCount(); + node->setRegister(trgReg); + return trgReg; + } + TR::Register * OMR::ARM64::TreeEvaluator::i2fEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::i2fEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::scvtf_wtos, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::i2dEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::i2dEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::scvtf_wtod, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::l2fEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::l2fEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::scvtf_xtos, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::l2dEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::l2dEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::scvtf_xtod, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::f2dEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::f2dEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::fcvt_stod, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::f2iEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::f2iEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::fcvtzs_stow, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::d2iEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::d2iEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::fcvtzs_dtow, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::d2cEvaluator(TR::Node *node, TR::CodeGenerator *cg) @@ -299,24 +316,21 @@ OMR::ARM64::TreeEvaluator::d2bEvaluator(TR::Node *node, TR::CodeGenerator *cg) TR::Register * OMR::ARM64::TreeEvaluator::f2lEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::f2lEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::fcvtzs_stox, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::d2lEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::d2lEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::fcvtzs_dtox, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::d2fEvaluator(TR::Node *node, TR::CodeGenerator *cg) - { - // TODO:ARM64: Enable TR::TreeEvaluator::d2fEvaluator in compiler/aarch64/codegen/TreeEvaluatorTable.hpp when Implemented. - return OMR::ARM64::TreeEvaluator::unImpOpEvaluator(node, cg); - } + { + return intFpTypeCoversionHelper(node, TR::InstOpCode::fcvt_dtos, cg); + } TR::Register * OMR::ARM64::TreeEvaluator::ifdcmpeqEvaluator(TR::Node *node, TR::CodeGenerator *cg) diff --git a/compiler/aarch64/codegen/OMRInstOpCodeEnum.hpp b/compiler/aarch64/codegen/OMRInstOpCodeEnum.hpp index 1c8eceace86..1b5ed5ea21d 100644 --- a/compiler/aarch64/codegen/OMRInstOpCodeEnum.hpp +++ b/compiler/aarch64/codegen/OMRInstOpCodeEnum.hpp @@ -424,8 +424,20 @@ /* VFP instructions */ fmovs, /* 0x1E204000 FMOV */ fmovd, /* 0x1E604000 FMOV */ + fmov_stow, /* 0x1E260000 FMOV */ fmov_wtos, /* 0x1E270000 FMOV */ + fmov_dtox, /* 0x9E660000 FMOV */ fmov_xtod, /* 0x9E670000 FMOV */ + fcvt_stod, /* 0x1E22C000 FCVT */ + fcvt_dtos, /* 0x1E624000 FCVT */ + fcvtzs_stow, /* 0x1E380000 FCVTZS */ + fcvtzs_dtow, /* 0x1E780000 FCVTZS */ + fcvtzs_stox, /* 0x9E380000 FCVTZS */ + fcvtzs_dtox, /* 0x9E780000 FCVTZS */ + scvtf_wtos, /* 0x1E220000 SCVTF */ + scvtf_wtod, /* 0x1E620000 SCVTF */ + scvtf_xtos, /* 0x9E220000 SCVTF */ + scvtf_xtod, /* 0x9E620000 SCVTF */ /* Internal OpCodes */ proc, // Entry to the method fence, // Fence diff --git a/compiler/aarch64/codegen/OpBinary.cpp b/compiler/aarch64/codegen/OpBinary.cpp index a4be101d6ce..a6194837665 100644 --- a/compiler/aarch64/codegen/OpBinary.cpp +++ b/compiler/aarch64/codegen/OpBinary.cpp @@ -423,6 +423,18 @@ const OMR::ARM64::InstOpCode::OpCodeBinaryEntry OMR::ARM64::InstOpCode::binaryEn /* VFP instructions */ 0x1E204000, /* FMOV fmovs */ 0x1E604000, /* FMOV fmovd */ + 0x1E260000, /* FMOV fmov_stow */ 0x1E270000, /* FMOV fmov_wtos */ + 0x9E660000, /* FMOV fmov_dtox */ 0x9E670000, /* FMOV fmov_xtod */ + 0x1E22C000, /* FCVT fcvt_stod */ + 0x1E624000, /* FCVT fcvt_dtos */ + 0x1E380000, /* FCVTZS fcvtzs_stow */ + 0x1E780000, /* FCVTZS fcvtzs_dtow */ + 0x9E380000, /* FCVTZS fcvtzs_stox */ + 0x9E780000, /* FCVTZS fcvtzs_dtox */ + 0x1E220000, /* SCVTF scvtf_wtos */ + 0x1E620000, /* SCVTF scvtf_wtod */ + 0x9E220000, /* SCVTF scvtf_xtos */ + 0x9E620000, /* SCVTF scvtf_xtod */ }; diff --git a/compiler/aarch64/codegen/TreeEvaluatorTable.hpp b/compiler/aarch64/codegen/TreeEvaluatorTable.hpp index 889efa761ca..18bb91418df 100644 --- a/compiler/aarch64/codegen/TreeEvaluatorTable.hpp +++ b/compiler/aarch64/codegen/TreeEvaluatorTable.hpp @@ -175,8 +175,8 @@ TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::bxorEvaluator , // TR::bxor // boolean xor of 2 bytes TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::sxorEvaluator , // TR::sxor // boolean xor of 2 short integers TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::i2lEvaluator , // TR::i2l // convert integer to long integer with sign extension - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::i2fEvaluator , // TR::i2f // convert integer to float - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::i2dEvaluator , // TR::i2d // convert integer to double + TR::TreeEvaluator::i2fEvaluator, // TR::i2f // convert integer to float + TR::TreeEvaluator::i2dEvaluator, // TR::i2d // convert integer to double TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::i2bEvaluator , // TR::i2b // convert integer to byte TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::i2sEvaluator , // TR::i2s // convert integer to short integer TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::i2aEvaluator , // TR::i2a // convert integer to address @@ -185,22 +185,22 @@ TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::iu2dEvaluator , // TR::iu2d // convert unsigned integer to double TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::iu2aEvaluator , // TR::iu2a // convert unsigned integer to address TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::l2iEvaluator , // TR::l2i // convert long integer to integer - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::l2fEvaluator , // TR::l2f // convert long integer to float - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::l2dEvaluator , // TR::l2d // convert long integer to double + TR::TreeEvaluator::l2fEvaluator, // TR::l2f // convert long integer to float + TR::TreeEvaluator::l2dEvaluator, // TR::l2d // convert long integer to double TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::l2bEvaluator , // TR::l2b // convert long integer to byte TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::l2sEvaluator , // TR::l2s // convert long integer to short integer TR::TreeEvaluator::passThroughEvaluator, // TR::l2a // convert long integer to address TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::lu2fEvaluator , // TR::lu2f // convert unsigned long integer to float TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::lu2dEvaluator , // TR::lu2d // convert unsigned long integer to double TR::TreeEvaluator::passThroughEvaluator, // TR::lu2a // convert unsigned long integer to address - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::f2iEvaluator , // TR::f2i // convert float to integer - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::f2lEvaluator , // TR::f2l // convert float to long integer - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::f2dEvaluator , // TR::f2d // convert float to double + TR::TreeEvaluator::f2iEvaluator, // TR::f2i // convert float to integer + TR::TreeEvaluator::f2lEvaluator, // TR::f2l // convert float to long integer + TR::TreeEvaluator::f2dEvaluator, // TR::f2d // convert float to double TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::f2bEvaluator , // TR::f2b // convert float to byte TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::f2sEvaluator , // TR::f2s // convert float to short integer - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::d2iEvaluator , // TR::d2i // convert double to integer - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::d2lEvaluator , // TR::d2l // convert double to long integer - TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::d2fEvaluator , // TR::d2f // convert double to float + TR::TreeEvaluator::d2iEvaluator, // TR::d2i // convert double to integer + TR::TreeEvaluator::d2lEvaluator, // TR::d2l // convert double to long integer + TR::TreeEvaluator::d2fEvaluator, // TR::d2f // convert double to float TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::d2bEvaluator , // TR::d2b // convert double to byte TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::d2sEvaluator , // TR::d2s // convert double to short integer TR::TreeEvaluator::unImpOpEvaluator , // TODO:ARM64: Enable when Implemented: TR::TreeEvaluator::b2iEvaluator , // TR::b2i // convert byte to integer with sign extension