qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

memop.h (3635B)


      1 /*
      2  * Constants for memory operations
      3  *
      4  * Authors:
      5  *  Richard Henderson <rth@twiddle.net>
      6  *
      7  * This work is licensed under the terms of the GNU GPL, version 2 or later.
      8  * See the COPYING file in the top-level directory.
      9  *
     10  */
     11 
     12 #ifndef MEMOP_H
     13 #define MEMOP_H
     14 
     15 #include "qemu/host-utils.h"
     16 
     17 typedef enum MemOp {
     18     MO_8     = 0,
     19     MO_16    = 1,
     20     MO_32    = 2,
     21     MO_64    = 3,
     22     MO_128   = 4,
     23     MO_256   = 5,
     24     MO_512   = 6,
     25     MO_1024  = 7,
     26     MO_SIZE  = 0x07,   /* Mask for the above.  */
     27 
     28     MO_SIGN  = 0x08,   /* Sign-extended, otherwise zero-extended.  */
     29 
     30     MO_BSWAP = 0x10,   /* Host reverse endian.  */
     31 #if HOST_BIG_ENDIAN
     32     MO_LE    = MO_BSWAP,
     33     MO_BE    = 0,
     34 #else
     35     MO_LE    = 0,
     36     MO_BE    = MO_BSWAP,
     37 #endif
     38 #ifdef NEED_CPU_H
     39 #if TARGET_BIG_ENDIAN
     40     MO_TE    = MO_BE,
     41 #else
     42     MO_TE    = MO_LE,
     43 #endif
     44 #endif
     45 
     46     /*
     47      * MO_UNALN accesses are never checked for alignment.
     48      * MO_ALIGN accesses will result in a call to the CPU's
     49      * do_unaligned_access hook if the guest address is not aligned.
     50      * The default depends on whether the target CPU defines
     51      * TARGET_ALIGNED_ONLY.
     52      *
     53      * Some architectures (e.g. ARMv8) need the address which is aligned
     54      * to a size more than the size of the memory access.
     55      * Some architectures (e.g. SPARCv9) need an address which is aligned,
     56      * but less strictly than the natural alignment.
     57      *
     58      * MO_ALIGN supposes the alignment size is the size of a memory access.
     59      *
     60      * There are three options:
     61      * - unaligned access permitted (MO_UNALN).
     62      * - an alignment to the size of an access (MO_ALIGN);
     63      * - an alignment to a specified size, which may be more or less than
     64      *   the access size (MO_ALIGN_x where 'x' is a size in bytes);
     65      */
     66     MO_ASHIFT = 5,
     67     MO_AMASK = 0x7 << MO_ASHIFT,
     68 #ifdef NEED_CPU_H
     69 #ifdef TARGET_ALIGNED_ONLY
     70     MO_ALIGN = 0,
     71     MO_UNALN = MO_AMASK,
     72 #else
     73     MO_ALIGN = MO_AMASK,
     74     MO_UNALN = 0,
     75 #endif
     76 #endif
     77     MO_ALIGN_2  = 1 << MO_ASHIFT,
     78     MO_ALIGN_4  = 2 << MO_ASHIFT,
     79     MO_ALIGN_8  = 3 << MO_ASHIFT,
     80     MO_ALIGN_16 = 4 << MO_ASHIFT,
     81     MO_ALIGN_32 = 5 << MO_ASHIFT,
     82     MO_ALIGN_64 = 6 << MO_ASHIFT,
     83 
     84     /* Combinations of the above, for ease of use.  */
     85     MO_UB    = MO_8,
     86     MO_UW    = MO_16,
     87     MO_UL    = MO_32,
     88     MO_UQ    = MO_64,
     89     MO_UO    = MO_128,
     90     MO_SB    = MO_SIGN | MO_8,
     91     MO_SW    = MO_SIGN | MO_16,
     92     MO_SL    = MO_SIGN | MO_32,
     93     MO_SQ    = MO_SIGN | MO_64,
     94     MO_SO    = MO_SIGN | MO_128,
     95 
     96     MO_LEUW  = MO_LE | MO_UW,
     97     MO_LEUL  = MO_LE | MO_UL,
     98     MO_LEUQ  = MO_LE | MO_UQ,
     99     MO_LESW  = MO_LE | MO_SW,
    100     MO_LESL  = MO_LE | MO_SL,
    101     MO_LESQ  = MO_LE | MO_SQ,
    102 
    103     MO_BEUW  = MO_BE | MO_UW,
    104     MO_BEUL  = MO_BE | MO_UL,
    105     MO_BEUQ  = MO_BE | MO_UQ,
    106     MO_BESW  = MO_BE | MO_SW,
    107     MO_BESL  = MO_BE | MO_SL,
    108     MO_BESQ  = MO_BE | MO_SQ,
    109 
    110 #ifdef NEED_CPU_H
    111     MO_TEUW  = MO_TE | MO_UW,
    112     MO_TEUL  = MO_TE | MO_UL,
    113     MO_TEUQ  = MO_TE | MO_UQ,
    114     MO_TEUO  = MO_TE | MO_UO,
    115     MO_TESW  = MO_TE | MO_SW,
    116     MO_TESL  = MO_TE | MO_SL,
    117     MO_TESQ  = MO_TE | MO_SQ,
    118 #endif
    119 
    120     MO_SSIZE = MO_SIZE | MO_SIGN,
    121 } MemOp;
    122 
    123 /* MemOp to size in bytes.  */
    124 static inline unsigned memop_size(MemOp op)
    125 {
    126     return 1 << (op & MO_SIZE);
    127 }
    128 
    129 /* Size in bytes to MemOp.  */
    130 static inline MemOp size_memop(unsigned size)
    131 {
    132 #ifdef CONFIG_DEBUG_TCG
    133     /* Power of 2 up to 8.  */
    134     assert((size & (size - 1)) == 0 && size >= 1 && size <= 8);
    135 #endif
    136     return ctz32(size);
    137 }
    138 
    139 /* Big endianness from MemOp.  */
    140 static inline bool memop_big_endian(MemOp op)
    141 {
    142     return (op & MO_BSWAP) == MO_BE;
    143 }
    144 
    145 #endif