1 /* 2 * Register Definition API: field macros 3 * 4 * Copyright (c) 2016 Xilinx Inc. 5 * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com> 6 * 7 * This work is licensed under the terms of the GNU GPL, version 2. See 8 * the COPYING file in the top-level directory. 9 */ 10 11 #ifndef REGISTERFIELDS_H 12 #define REGISTERFIELDS_H 13 14 #include "qemu/bitops.h" 15 16 /* Define constants for a 32 bit register */ 17 18 /* This macro will define A_FOO, for the byte address of a register 19 * as well as R_FOO for the uint32_t[] register number (A_FOO / 4). 20 */ 21 #define REG32(reg, addr) \ 22 enum { A_ ## reg = (addr) }; \ 23 enum { R_ ## reg = (addr) / 4 }; 24 25 #define REG8(reg, addr) \ 26 enum { A_ ## reg = (addr) }; \ 27 enum { R_ ## reg = (addr) }; 28 29 #define REG16(reg, addr) \ 30 enum { A_ ## reg = (addr) }; \ 31 enum { R_ ## reg = (addr) / 2 }; 32 33 #define REG64(reg, addr) \ 34 enum { A_ ## reg = (addr) }; \ 35 enum { R_ ## reg = (addr) / 8 }; 36 37 /* Define SHIFT, LENGTH and MASK constants for a field within a register */ 38 39 /* This macro will define R_FOO_BAR_MASK, R_FOO_BAR_SHIFT and R_FOO_BAR_LENGTH 40 * constants for field BAR in register FOO. 41 */ 42 #define FIELD(reg, field, shift, length) \ 43 enum { R_ ## reg ## _ ## field ## _SHIFT = (shift)}; \ 44 enum { R_ ## reg ## _ ## field ## _LENGTH = (length)}; \ 45 enum { R_ ## reg ## _ ## field ## _MASK = \ 46 MAKE_64BIT_MASK(shift, length)}; 47 48 /* Extract a field from a register */ 49 #define FIELD_EX8(storage, reg, field) \ 50 extract8((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 51 R_ ## reg ## _ ## field ## _LENGTH) 52 #define FIELD_EX16(storage, reg, field) \ 53 extract16((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 54 R_ ## reg ## _ ## field ## _LENGTH) 55 #define FIELD_EX32(storage, reg, field) \ 56 extract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 57 R_ ## reg ## _ ## field ## _LENGTH) 58 #define FIELD_EX64(storage, reg, field) \ 59 extract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 60 R_ ## reg ## _ ## field ## _LENGTH) 61 62 #define FIELD_SEX8(storage, reg, field) \ 63 sextract8((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 64 R_ ## reg ## _ ## field ## _LENGTH) 65 #define FIELD_SEX16(storage, reg, field) \ 66 sextract16((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 67 R_ ## reg ## _ ## field ## _LENGTH) 68 #define FIELD_SEX32(storage, reg, field) \ 69 sextract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 70 R_ ## reg ## _ ## field ## _LENGTH) 71 #define FIELD_SEX64(storage, reg, field) \ 72 sextract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 73 R_ ## reg ## _ ## field ## _LENGTH) 74 75 /* Extract a field from an array of registers */ 76 #define ARRAY_FIELD_EX32(regs, reg, field) \ 77 FIELD_EX32((regs)[R_ ## reg], reg, field) 78 #define ARRAY_FIELD_EX64(regs, reg, field) \ 79 FIELD_EX64((regs)[R_ ## reg], reg, field) 80 81 /* Deposit a register field. 82 * Assigning values larger then the target field will result in 83 * compilation warnings. 84 */ 85 #define FIELD_DP8(storage, reg, field, val) ({ \ 86 struct { \ 87 unsigned int v:R_ ## reg ## _ ## field ## _LENGTH; \ 88 } _v = { .v = val }; \ 89 uint8_t _d; \ 90 _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 91 R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ 92 _d; }) 93 #define FIELD_DP16(storage, reg, field, val) ({ \ 94 struct { \ 95 unsigned int v:R_ ## reg ## _ ## field ## _LENGTH; \ 96 } _v = { .v = val }; \ 97 uint16_t _d; \ 98 _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 99 R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ 100 _d; }) 101 #define FIELD_DP32(storage, reg, field, val) ({ \ 102 struct { \ 103 unsigned int v:R_ ## reg ## _ ## field ## _LENGTH; \ 104 } _v = { .v = val }; \ 105 uint32_t _d; \ 106 _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 107 R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ 108 _d; }) 109 #define FIELD_DP64(storage, reg, field, val) ({ \ 110 struct { \ 111 uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \ 112 } _v = { .v = val }; \ 113 uint64_t _d; \ 114 _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 115 R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ 116 _d; }) 117 118 #define FIELD_SDP8(storage, reg, field, val) ({ \ 119 struct { \ 120 signed int v:R_ ## reg ## _ ## field ## _LENGTH; \ 121 } _v = { .v = val }; \ 122 uint8_t _d; \ 123 _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 124 R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ 125 _d; }) 126 #define FIELD_SDP16(storage, reg, field, val) ({ \ 127 struct { \ 128 signed int v:R_ ## reg ## _ ## field ## _LENGTH; \ 129 } _v = { .v = val }; \ 130 uint16_t _d; \ 131 _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 132 R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ 133 _d; }) 134 #define FIELD_SDP32(storage, reg, field, val) ({ \ 135 struct { \ 136 signed int v:R_ ## reg ## _ ## field ## _LENGTH; \ 137 } _v = { .v = val }; \ 138 uint32_t _d; \ 139 _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 140 R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ 141 _d; }) 142 #define FIELD_SDP64(storage, reg, field, val) ({ \ 143 struct { \ 144 int64_t v:R_ ## reg ## _ ## field ## _LENGTH; \ 145 } _v = { .v = val }; \ 146 uint64_t _d; \ 147 _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \ 148 R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ 149 _d; }) 150 151 /* Deposit a field to array of registers. */ 152 #define ARRAY_FIELD_DP32(regs, reg, field, val) \ 153 (regs)[R_ ## reg] = FIELD_DP32((regs)[R_ ## reg], reg, field, val); 154 #define ARRAY_FIELD_DP64(regs, reg, field, val) \ 155 (regs)[R_ ## reg] = FIELD_DP64((regs)[R_ ## reg], reg, field, val); 156 157 158 /* 159 * These macros can be used for defining and extracting fields that have the 160 * same bit position across multiple registers. 161 */ 162 163 /* Define shared SHIFT, LENGTH, and MASK constants */ 164 #define SHARED_FIELD(name, shift, length) \ 165 enum { name ## _ ## SHIFT = (shift)}; \ 166 enum { name ## _ ## LENGTH = (length)}; \ 167 enum { name ## _ ## MASK = MAKE_64BIT_MASK(shift, length)}; 168 169 /* Extract a shared field */ 170 #define SHARED_FIELD_EX8(storage, field) \ 171 extract8((storage), field ## _SHIFT, field ## _LENGTH) 172 173 #define SHARED_FIELD_EX16(storage, field) \ 174 extract16((storage), field ## _SHIFT, field ## _LENGTH) 175 176 #define SHARED_FIELD_EX32(storage, field) \ 177 extract32((storage), field ## _SHIFT, field ## _LENGTH) 178 179 #define SHARED_FIELD_EX64(storage, field) \ 180 extract64((storage), field ## _SHIFT, field ## _LENGTH) 181 182 /* Extract a shared field from a register array */ 183 #define SHARED_ARRAY_FIELD_EX32(regs, offset, field) \ 184 SHARED_FIELD_EX32((regs)[(offset)], field) 185 #define SHARED_ARRAY_FIELD_EX64(regs, offset, field) \ 186 SHARED_FIELD_EX64((regs)[(offset)], field) 187 188 /* Deposit a shared field */ 189 #define SHARED_FIELD_DP8(storage, field, val) ({ \ 190 struct { \ 191 unsigned int v:field ## _LENGTH; \ 192 } _v = { .v = val }; \ 193 uint8_t _d; \ 194 _d = deposit32((storage), field ## _SHIFT, field ## _LENGTH, _v.v); \ 195 _d; }) 196 197 #define SHARED_FIELD_DP16(storage, field, val) ({ \ 198 struct { \ 199 unsigned int v:field ## _LENGTH; \ 200 } _v = { .v = val }; \ 201 uint16_t _d; \ 202 _d = deposit32((storage), field ## _SHIFT, field ## _LENGTH, _v.v); \ 203 _d; }) 204 205 #define SHARED_FIELD_DP32(storage, field, val) ({ \ 206 struct { \ 207 unsigned int v:field ## _LENGTH; \ 208 } _v = { .v = val }; \ 209 uint32_t _d; \ 210 _d = deposit32((storage), field ## _SHIFT, field ## _LENGTH, _v.v); \ 211 _d; }) 212 213 #define SHARED_FIELD_DP64(storage, field, val) ({ \ 214 struct { \ 215 uint64_t v:field ## _LENGTH; \ 216 } _v = { .v = val }; \ 217 uint64_t _d; \ 218 _d = deposit64((storage), field ## _SHIFT, field ## _LENGTH, _v.v); \ 219 _d; }) 220 221 /* Deposit a shared field to a register array */ 222 #define SHARED_ARRAY_FIELD_DP32(regs, offset, field, val) \ 223 (regs)[(offset)] = SHARED_FIELD_DP32((regs)[(offset)], field, val); 224 #define SHARED_ARRAY_FIELD_DP64(regs, offset, field, val) \ 225 (regs)[(offset)] = SHARED_FIELD_DP64((regs)[(offset)], field, val); 226 227 #endif 228