blob: 2c1dbf8aa9116ded88e463655fde21e1efe1c553 [file] [log] [blame]
/*
* Copyright (C) 2020 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.
*/
#ifndef RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_FLOATING_POINT_IMPL_H_
#define RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_FLOATING_POINT_IMPL_H_
#include "berberis/base/bit_util.h"
#include "berberis/intrinsics/macro_assembler.h"
#include "berberis/intrinsics/macro_assembler_constants_pool.h"
namespace berberis {
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::CanonicalizeNan(XMMRegister result, XMMRegister src) {
Pmov(result, src);
Cmpords<FloatType>(result, src);
Pand(src, result);
Pandn(result, {.disp = constants_pool::kCanonicalNans<FloatType>});
Por(result, src);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::CanonicalizeNanAVX(XMMRegister result, XMMRegister src) {
Vcmpords<FloatType>(result, src, src);
Vpand(src, src, result);
Vpandn(result, result, {.disp = constants_pool::kCanonicalNans<FloatType>});
Vpor(result, result, src);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroFeq(Register result, XMMRegister src1, XMMRegister src2) {
Cmpeqs<FloatType>(src1, src2);
Mov<FloatType>(result, src1);
Andl(result, 1);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroFeqAVX(Register result,
XMMRegister src1,
XMMRegister src2,
XMMRegister tmp) {
Vcmpeqs<FloatType>(tmp, src1, src2);
Mov<FloatType>(result, tmp);
Andl(result, 1);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroFle(Register result, XMMRegister src1, XMMRegister src2) {
Cmples<FloatType>(src1, src2);
Mov<FloatType>(result, src1);
Andl(result, 1);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroFleAVX(Register result,
XMMRegister src1,
XMMRegister src2,
XMMRegister tmp) {
Vcmples<FloatType>(tmp, src1, src2);
Mov<FloatType>(result, tmp);
Andl(result, 1);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroFlt(Register result, XMMRegister src1, XMMRegister src2) {
Cmplts<FloatType>(src1, src2);
Mov<FloatType>(result, src1);
Andl(result, 1);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroFltAVX(Register result,
XMMRegister src1,
XMMRegister src2,
XMMRegister tmp) {
Vcmplts<FloatType>(tmp, src1, src2);
Mov<FloatType>(result, tmp);
Andl(result, 1);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroNanBox(XMMRegister arg) {
static_assert(std::is_same_v<FloatType, Float32>);
Por(arg, {.disp = constants_pool::kNanBox<Float32>});
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroNanBoxAVX(XMMRegister arg) {
static_assert(std::is_same_v<FloatType, Float32>);
Vpor(arg, arg, {.disp = constants_pool::kNanBox<Float32>});
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroUnboxNan(XMMRegister result, XMMRegister src) {
static_assert(std::is_same_v<FloatType, Float32>);
Pmov(result, src);
Pcmpeq<typename TypeTraits<FloatType>::Int>(result, {.disp = constants_pool::kNanBox<Float32>});
Pshufd(result, result, kShuffleDDBB);
Pand(src, result);
Pandn(result, {.disp = constants_pool::kNanBoxedNans<Float32>});
Por(result, src);
}
template <typename Assembler>
template <typename FloatType>
void MacroAssembler<Assembler>::MacroUnboxNanAVX(XMMRegister result, XMMRegister src) {
static_assert(std::is_same_v<FloatType, Float32>);
Vpcmpeq<typename TypeTraits<FloatType>::Int>(
result, src, {.disp = constants_pool::kNanBox<Float32>});
Vpshufd(result, result, kShuffleDDBB);
Vpand(src, src, result);
Vpandn(result, result, {.disp = constants_pool::kNanBoxedNans<Float32>});
Vpor(result, result, src);
}
} // namespace berberis
#endif // RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_FLOATING_POINT_IMPL_H_