1 // AsmJit - Machine code generation for C++
2 //
3 //  * Official AsmJit Home Page: https://asmjit.com
4 //  * Official Github Repository: https://github.com/asmjit/asmjit
5 //
6 // Copyright (c) 2008-2020 The AsmJit Authors
7 //
8 // This software is provided 'as-is', without any express or implied
9 // warranty. In no event will the authors be held liable for any damages
10 // arising from the use of this software.
11 //
12 // Permission is granted to anyone to use this software for any purpose,
13 // including commercial applications, and to alter it and redistribute it
14 // freely, subject to the following restrictions:
15 //
16 // 1. The origin of this software must not be misrepresented; you must not
17 //    claim that you wrote the original software. If you use this software
18 //    in a product, an acknowledgment in the product documentation would be
19 //    appreciated but is not required.
20 // 2. Altered source versions must be plainly marked as such, and must not be
21 //    misrepresented as being the original software.
22 // 3. This notice may not be removed or altered from any source distribution.
23 
24 #ifndef ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED
25 #define ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED
26 
27 #include "../core/emitter.h"
28 #include "../core/operand.h"
29 
30 ASMJIT_BEGIN_NAMESPACE
31 
32 class BaseAssembler;
33 
34 //! \cond INTERNAL
35 //! \addtogroup asmjit_core
36 //! \{
37 
38 // ============================================================================
39 // [asmjit::EmitterUtils]
40 // ============================================================================
41 
42 namespace EmitterUtils {
43 
44 static const Operand_ noExt[3] {};
45 
46 enum kOpIndex {
47   kOp3 = 0,
48   kOp4 = 1,
49   kOp5 = 2
50 };
51 
opCountFromEmitArgs(const Operand_ & o0,const Operand_ & o1,const Operand_ & o2,const Operand_ * opExt)52 static ASMJIT_INLINE uint32_t opCountFromEmitArgs(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept {
53   uint32_t opCount = 0;
54 
55   if (opExt[kOp3].isNone()) {
56     if (!o0.isNone()) opCount = 1;
57     if (!o1.isNone()) opCount = 2;
58     if (!o2.isNone()) opCount = 3;
59   }
60   else {
61     opCount = 4;
62     if (!opExt[kOp4].isNone()) {
63       opCount = 5 + uint32_t(!opExt[kOp5].isNone());
64     }
65   }
66 
67   return opCount;
68 }
69 
opArrayFromEmitArgs(Operand_ dst[Globals::kMaxOpCount],const Operand_ & o0,const Operand_ & o1,const Operand_ & o2,const Operand_ * opExt)70 static ASMJIT_INLINE void opArrayFromEmitArgs(Operand_ dst[Globals::kMaxOpCount], const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept {
71   dst[0].copyFrom(o0);
72   dst[1].copyFrom(o1);
73   dst[2].copyFrom(o2);
74   dst[3].copyFrom(opExt[kOp3]);
75   dst[4].copyFrom(opExt[kOp4]);
76   dst[5].copyFrom(opExt[kOp5]);
77 }
78 
79 #ifndef ASMJIT_NO_LOGGING
80 enum : uint32_t {
81   // Has to be big to be able to hold all metadata compiler can assign to a
82   // single instruction.
83   kMaxInstLineSize = 44,
84   kMaxBinarySize = 26
85 };
86 
87 Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept;
88 
89 void logLabelBound(BaseAssembler* self, const Label& label) noexcept;
90 
91 void logInstructionEmitted(
92   BaseAssembler* self,
93   uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt,
94   uint32_t relSize, uint32_t immSize, uint8_t* afterCursor);
95 
96 Error logInstructionFailed(
97   BaseAssembler* self,
98   Error err, uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt);
99 #endif
100 
101 }
102 
103 //! \}
104 //! \endcond
105 
106 ASMJIT_END_NAMESPACE
107 
108 #endif // ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED
109 
110