You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
6.6 KiB
165 lines
6.6 KiB
// AsmJit - Machine code generation for C++
|
|
//
|
|
// * Official AsmJit Home Page: https://asmjit.com
|
|
// * Official Github Repository: https://github.com/asmjit/asmjit
|
|
//
|
|
// Copyright (c) 2008-2020 The AsmJit Authors
|
|
//
|
|
// This software is provided 'as-is', without any express or implied
|
|
// warranty. In no event will the authors be held liable for any damages
|
|
// arising from the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
// including commercial applications, and to alter it and redistribute it
|
|
// freely, subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented; you must not
|
|
// claim that you wrote the original software. If you use this software
|
|
// in a product, an acknowledgment in the product documentation would be
|
|
// appreciated but is not required.
|
|
// 2. Altered source versions must be plainly marked as such, and must not be
|
|
// misrepresented as being the original software.
|
|
// 3. This notice may not be removed or altered from any source distribution.
|
|
|
|
#ifndef ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED
|
|
#define ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED
|
|
|
|
// This file provides architecture-specific classes that are required in the
|
|
// core library. For example Imm operand allows to be created from arm::Shift
|
|
// in a const-expr way, so the arm::Shift must be provided. So this header
|
|
// file provides everything architecture-specific that is used by the Core API.
|
|
|
|
#include "../core/globals.h"
|
|
|
|
// ============================================================================
|
|
// [asmjit::arm]
|
|
// ============================================================================
|
|
|
|
ASMJIT_BEGIN_SUB_NAMESPACE(arm)
|
|
|
|
//! \addtogroup asmjit_arm
|
|
//! \{
|
|
|
|
//! Represents ARM immediate shift operation type and value.
|
|
class Shift {
|
|
public:
|
|
//! Operation predicate (ARM) describes either SHIFT or EXTEND operation.
|
|
//!
|
|
//! \note The constants are AsmJit specific. The first 5 values describe real
|
|
//! constants on ARM32 and AArch64 hardware, however, the addition constants
|
|
//! that describe extend modes are specific to AsmJit and would be translated
|
|
//! to the AArch64 specific constants by the assembler.
|
|
enum Op : uint32_t {
|
|
//! Shift left logical operation (default).
|
|
//!
|
|
//! Available to all ARM architectures.
|
|
kOpLSL = 0x00u,
|
|
|
|
//! Shift right logical operation.
|
|
//!
|
|
//! Available to all ARM architectures.
|
|
kOpLSR = 0x01u,
|
|
|
|
//! Shift right arithmetic operation.
|
|
//!
|
|
//! Available to all ARM architectures.
|
|
kOpASR = 0x02u,
|
|
|
|
//! Rotate right operation.
|
|
//!
|
|
//! \note Not available in AArch64 mode.
|
|
kOpROR = 0x03u,
|
|
|
|
//! Rotate right with carry operation (encoded as `kShiftROR` with zero).
|
|
//!
|
|
//! \note Not available in AArch64 mode.
|
|
kOpRRX = 0x04u,
|
|
|
|
//! Shift left by filling low order bits with ones.
|
|
kOpMSL = 0x05u,
|
|
|
|
//! UXTN extend register operation (AArch64 only).
|
|
kOpUXTB = 0x06u,
|
|
//! UXTH extend register operation (AArch64 only).
|
|
kOpUXTH = 0x07u,
|
|
//! UXTW extend register operation (AArch64 only).
|
|
kOpUXTW = 0x08u,
|
|
//! UXTX extend register operation (AArch64 only).
|
|
kOpUXTX = 0x09u,
|
|
|
|
//! SXTB extend register operation (AArch64 only).
|
|
kOpSXTB = 0x0Au,
|
|
//! SXTH extend register operation (AArch64 only).
|
|
kOpSXTH = 0x0Bu,
|
|
//! SXTW extend register operation (AArch64 only).
|
|
kOpSXTW = 0x0Cu,
|
|
//! SXTX extend register operation (AArch64 only).
|
|
kOpSXTX = 0x0Du
|
|
|
|
// NOTE: 0xE and 0xF are used by memory operand to specify POST|PRE offset mode.
|
|
};
|
|
|
|
//! Shift operation.
|
|
uint32_t _op;
|
|
//! Shift Value.
|
|
uint32_t _value;
|
|
|
|
//! Default constructed Shift is not initialized.
|
|
inline Shift() noexcept = default;
|
|
|
|
//! Copy constructor (default)
|
|
constexpr Shift(const Shift& other) noexcept = default;
|
|
|
|
//! Constructs Shift from operation `op` and shift `value`.
|
|
constexpr Shift(uint32_t op, uint32_t value) noexcept
|
|
: _op(op),
|
|
_value(value) {}
|
|
|
|
//! Returns the shift operation.
|
|
constexpr uint32_t op() const noexcept { return _op; }
|
|
//! Returns the shift smount.
|
|
constexpr uint32_t value() const noexcept { return _value; }
|
|
|
|
//! Sets shift operation to `op`.
|
|
inline void setOp(uint32_t op) noexcept { _op = op; }
|
|
//! Sets shift amount to `value`.
|
|
inline void setValue(uint32_t value) noexcept { _value = value; }
|
|
};
|
|
|
|
//! Constructs a `LSL #value` shift (logical shift left).
|
|
static constexpr Shift lsl(uint32_t value) noexcept { return Shift(Shift::kOpLSL, value); }
|
|
//! Constructs a `LSR #value` shift (logical shift right).
|
|
static constexpr Shift lsr(uint32_t value) noexcept { return Shift(Shift::kOpLSR, value); }
|
|
//! Constructs a `ASR #value` shift (arithmetic shift right).
|
|
static constexpr Shift asr(uint32_t value) noexcept { return Shift(Shift::kOpASR, value); }
|
|
//! Constructs a `ROR #value` shift (rotate right).
|
|
static constexpr Shift ror(uint32_t value) noexcept { return Shift(Shift::kOpROR, value); }
|
|
//! Constructs a `RRX` shift (rotate with carry by 1).
|
|
static constexpr Shift rrx() noexcept { return Shift(Shift::kOpRRX, 0); }
|
|
//! Constructs a `MSL #value` shift (logical shift left filling ones).
|
|
static constexpr Shift msl(uint32_t value) noexcept { return Shift(Shift::kOpMSL, value); }
|
|
|
|
//! Constructs a `UXTB #value` extend and shift (unsigned byte extend).
|
|
static constexpr Shift uxtb(uint32_t value) noexcept { return Shift(Shift::kOpUXTB, value); }
|
|
//! Constructs a `UXTH #value` extend and shift (unsigned hword extend).
|
|
static constexpr Shift uxth(uint32_t value) noexcept { return Shift(Shift::kOpUXTH, value); }
|
|
//! Constructs a `UXTW #value` extend and shift (unsigned word extend).
|
|
static constexpr Shift uxtw(uint32_t value) noexcept { return Shift(Shift::kOpUXTW, value); }
|
|
//! Constructs a `UXTX #value` extend and shift (unsigned dword extend).
|
|
static constexpr Shift uxtx(uint32_t value) noexcept { return Shift(Shift::kOpUXTX, value); }
|
|
|
|
//! Constructs a `SXTB #value` extend and shift (signed byte extend).
|
|
static constexpr Shift sxtb(uint32_t value) noexcept { return Shift(Shift::kOpSXTB, value); }
|
|
//! Constructs a `SXTH #value` extend and shift (signed hword extend).
|
|
static constexpr Shift sxth(uint32_t value) noexcept { return Shift(Shift::kOpSXTH, value); }
|
|
//! Constructs a `SXTW #value` extend and shift (signed word extend).
|
|
static constexpr Shift sxtw(uint32_t value) noexcept { return Shift(Shift::kOpSXTW, value); }
|
|
//! Constructs a `SXTX #value` extend and shift (signed dword extend).
|
|
static constexpr Shift sxtx(uint32_t value) noexcept { return Shift(Shift::kOpSXTX, value); }
|
|
|
|
//! \}
|
|
|
|
ASMJIT_END_SUB_NAMESPACE
|
|
|
|
#endif // ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED
|