/** * Copyright 2013, Landz and its contributors. All rights reserved. * * 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. */ package jnr.x86asm; import static jnr.x86asm.INST_CODE.*; /** * Assembler intrinsics seralizer. * * SerializerCore is abstract class that is used by @c Assembler and @a Compiler. * You probably never use this class directly, instead you use it to serialize * intrinsics to @c Assembler or @c Compiler. @c SerializerIntrinsics implements * all intruction intrinsics thats used and @c Serializer is public serializer * class that should be used (instead of @c SerializerCore or @c SerializerInstrinsics). * * <b>Note:</b> Use always {@link Serializer} class, this class is only designed to * decrease code size when exporting AsmJit library symbols. Some compilers * (for example MSVC) are exporting inline symbols when class is declared * to export them and {@link Serializer} class contains really huge count of * symbols that will be never used (everything is inlined). */ public abstract class SerializerCore { static final Operand _none = new Operand(OP.OP_NONE, 0) {}; //! @brief Emits X86/FPU or MM instruction. //! //! Operands @a o1, @a o2 or @a o3 can be @c NULL if they are not used. //! //! Hint: Use @c emitX86() helpers to emit instructions. abstract void _emitX86(INST_CODE code, Operand o1, Operand o2, Operand o3); // Helpers to decrease binary code size. These four emit methods are just // helpers thats used by serializer. They call _emitX86() adding NULLs // to first, second and third operand if needed. //! @brief Emits instruction with no operand. //! //! Should be use as an alternative to @c _emitX86() method. void emitX86(INST_CODE code) { _emitX86(code, _none, _none, _none); } //! @brief Emits instruction with one operand. //! //! Should be use as an alternative to @c _emitX86() method. void emitX86(INST_CODE code, Operand o1) { _emitX86(code, o1, _none, _none); } //! @brief Emits instruction with two operands. //! //! Should be use as an alternative to @c _emitX86() method. void emitX86(INST_CODE code, Operand o1, Operand o2) { _emitX86(code, o1, o2, _none); } //! @brief Emits instruction with three operands. //! //! Should be use as an alternative to @c _emitX86() method. void emitX86(INST_CODE code, Operand o1, Operand o2, Operand o3) { _emitX86(code, o1, o2, o3); } //! @brief Private method for emitting jcc. //! @internal This should be probably private. void _emitJcc(INST_CODE code, Label label, final int hint) { if (hint == 0) { emitX86(code, label); } else { emitX86(code, label, Immediate.imm(hint)); } } //! @brief Private method for emitting jcc. //! @internal This should be probably private. void _emitJcc(INST_CODE code, Label label, final HINT hint) { if (hint == HINT.HINT_NONE) { emitX86(code, label); } else { emitX86(code, label, Immediate.imm(hint.value())); } } abstract boolean is64(); //! @brief Translate condition code @a CC to AsmJit jump (jcc) instruction code. //! @sa @c INST_CODE, @c INST_J. static INST_CODE conditionToJCC(CONDITION cc) { assert (cc.value() <= 0xF); return _jcctable[cc.value()]; } //! @brief Translate condition code @a CC to AsmJit cmov (cmovcc) instruction code. //! @sa @c INST_CODE, @c INST_CMOV. static INST_CODE conditionToCMovCC(CONDITION cc) { assert (cc.value() <= 0xF); return _cmovcctable[cc.value()]; } //! @brief Translate condition code @a CC to AsmJit set (setcc) instruction code. //! @sa @c INST_CODE, @c INST_SET. static INST_CODE conditionToSetCC(CONDITION cc) { assert (cc.value() <= 0xF); return _setcctable[cc.value()]; } /** Map used for jcc instructions. */ static INST_CODE[] _jcctable = { INST_JO, INST_JNO, INST_JB, INST_JAE, INST_JE, INST_JNE, INST_JBE, INST_JA, INST_JS, INST_JNS, INST_JPE, INST_JPO, INST_JL, INST_JGE, INST_JLE, INST_JG }; /** Map used for cmovcc instructions. */ static INST_CODE[] _cmovcctable = { INST_CMOVO, INST_CMOVNO, INST_CMOVB, INST_CMOVAE, INST_CMOVE, INST_CMOVNE, INST_CMOVBE, INST_CMOVA, INST_CMOVS, INST_CMOVNS, INST_CMOVPE, INST_CMOVPO, INST_CMOVL, INST_CMOVGE, INST_CMOVLE, INST_CMOVG }; static final INST_CODE[] _setcctable = { INST_SETO, INST_SETNO, INST_SETB, INST_SETAE, INST_SETE, INST_SETNE, INST_SETBE, INST_SETA, INST_SETS, INST_SETNS, INST_SETPE, INST_SETPO, INST_SETL, INST_SETGE, INST_SETLE, INST_SETG }; }