1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_H_
18 #define RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_H_
19 
20 #include <limits.h>
21 #include <type_traits>  // is_same_v
22 
23 #include <functional>
24 #include <tuple>
25 #include <utility>
26 
27 // Don't include arch-dependent parts because macro-assembler doesn't depend on implementation of
28 // Float32/Float64 types but can be compiled for different architecture (soong's host architecture,
29 // not device architecture AKA berberis' host architecture).
30 #include "berberis/intrinsics/common/intrinsics_float.h"
31 #include "berberis/intrinsics/macro_assembler_constants_pool.h"
32 
33 namespace berberis {
34 
35 template <typename Assembler>
36 class MacroAssembler : public Assembler {
37  public:
38   using MacroAssemblers = std::tuple<MacroAssembler<Assembler>,
39                                      typename Assembler::BaseAssembler,
40                                      typename Assembler::FinalAssembler>;
41 
42   template <typename... Args>
MacroAssembler(Args &&...args)43   explicit MacroAssembler(Args&&... args) : Assembler(std::forward<Args>(args)...) {
44   }
45 
46 #define DEFINE_MACRO_ASSEMBLER_GENERIC_FUNCTIONS
47 #include "berberis/intrinsics/all_to_x86_32_or_x86_64/macro_assembler-inl.h"
48 
PNot(XMMRegister result)49   void PNot(XMMRegister result) {
50     Pandn(result, {.disp = constants_pool::kVectorConst<uint8_t{0b1111'1111}>});
51   }
52 
53   void Vpnot(XMMRegister result, XMMRegister src) {
54     Vpandn(result, src, {.disp = constants_pool::kVectorConst<uint8_t{0b1111'1111}>});
55   }
56 
57 #include "berberis/intrinsics/macro_assembler_interface-inl.h"  // NOLINT generated file
58 
59   using Assembler::Bind;
60   using Assembler::Btq;
61   using Assembler::Cbw;
62   using Assembler::Cdq;
63   using Assembler::Cqo;
64   using Assembler::Cwd;
65   using Assembler::Fldcw;
66   using Assembler::Fldenv;
67   using Assembler::Fnstcw;
68   using Assembler::Fnstenv;
69   using Assembler::Fnstsw;
70   using Assembler::Jcc;
71   using Assembler::Jmp;
72   using Assembler::Ldmxcsr;
73   using Assembler::Leal;
74   using Assembler::Leaq;
75   using Assembler::MakeLabel;
76   using Assembler::Movl;
77   using Assembler::Pand;
78   using Assembler::Pandn;
79   using Assembler::Pcmpeqb;
80   using Assembler::Pmov;
81   using Assembler::Por;
82   using Assembler::Pshufd;
83   using Assembler::Setcc;
84   using Assembler::Stmxcsr;
85   using Assembler::Vpand;
86   using Assembler::Vpandn;
87   using Assembler::Vpcmpeqb;
88   using Assembler::Vpor;
89   using Assembler::Vpshufd;
90 
91   using Assembler::Byte;
92   using Assembler::TwoByte;
93   using Assembler::FourByte;
94   using Assembler::EigthByte;
95   using Assembler::P2Align;
96 
97   using Assembler::gpr_a;
98   using Assembler::gpr_c;
99   using Assembler::gpr_d;
100 
101  private:
102 
103   // Useful constants for PshufXXX instructions.
104   enum {
105     kShuffleDDBB = 0b11110101
106   };
107 };
108 
109 }  // namespace berberis
110 
111 // Macro specializations.
112 #include "berberis/intrinsics/macro_assembler_arith_impl.h"
113 #include "berberis/intrinsics/macro_assembler_bitmanip_impl.h"
114 #include "berberis/intrinsics/macro_assembler_floating_point_impl.h"
115 
116 #endif  // RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_H_
117