duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

memref.c (17764B)


      1 #include "rc_internal.h"
      2 
      3 #include <stdlib.h> /* malloc/realloc */
      4 #include <string.h> /* memcpy */
      5 #include <math.h>   /* INFINITY/NAN */
      6 
      7 #define MEMREF_PLACEHOLDER_ADDRESS 0xFFFFFFFF
      8 
      9 rc_memref_t* rc_alloc_memref(rc_parse_state_t* parse, uint32_t address, uint8_t size, uint8_t is_indirect) {
     10   rc_memref_t** next_memref;
     11   rc_memref_t* memref;
     12 
     13   if (!is_indirect) {
     14     /* attempt to find an existing memref that can be shared */
     15     next_memref = parse->first_memref;
     16     while (*next_memref) {
     17       memref = *next_memref;
     18       if (!memref->value.is_indirect && memref->address == address && memref->value.size == size)
     19         return memref;
     20 
     21       next_memref = &memref->next;
     22     }
     23 
     24     /* no match found, create a new entry */
     25     memref = RC_ALLOC_SCRATCH(rc_memref_t, parse);
     26     *next_memref = memref;
     27   }
     28   else {
     29     /* indirect references always create a new entry because we can't guarantee that the 
     30      * indirection amount will be the same between references. because they aren't shared,
     31      * don't bother putting them in the chain.
     32      */
     33     memref = RC_ALLOC(rc_memref_t, parse);
     34   }
     35 
     36   memset(memref, 0, sizeof(*memref));
     37   memref->address = address;
     38   memref->value.size = size;
     39   memref->value.is_indirect = is_indirect;
     40 
     41   return memref;
     42 }
     43 
     44 int rc_parse_memref(const char** memaddr, uint8_t* size, uint32_t* address) {
     45   const char* aux = *memaddr;
     46   char* end;
     47   unsigned long value;
     48 
     49   if (aux[0] == '0') {
     50     if (aux[1] != 'x' && aux[1] != 'X')
     51       return RC_INVALID_MEMORY_OPERAND;
     52 
     53     aux += 2;
     54     switch (*aux++) {
     55       /* ordered by estimated frequency in case compiler doesn't build a jump table */
     56       case 'h': case 'H': *size = RC_MEMSIZE_8_BITS; break;
     57       case ' ':           *size = RC_MEMSIZE_16_BITS; break;
     58       case 'x': case 'X': *size = RC_MEMSIZE_32_BITS; break;
     59 
     60       case 'm': case 'M': *size = RC_MEMSIZE_BIT_0; break;
     61       case 'n': case 'N': *size = RC_MEMSIZE_BIT_1; break;
     62       case 'o': case 'O': *size = RC_MEMSIZE_BIT_2; break;
     63       case 'p': case 'P': *size = RC_MEMSIZE_BIT_3; break;
     64       case 'q': case 'Q': *size = RC_MEMSIZE_BIT_4; break;
     65       case 'r': case 'R': *size = RC_MEMSIZE_BIT_5; break;
     66       case 's': case 'S': *size = RC_MEMSIZE_BIT_6; break;
     67       case 't': case 'T': *size = RC_MEMSIZE_BIT_7; break;
     68       case 'l': case 'L': *size = RC_MEMSIZE_LOW; break;
     69       case 'u': case 'U': *size = RC_MEMSIZE_HIGH; break;
     70       case 'k': case 'K': *size = RC_MEMSIZE_BITCOUNT; break;
     71       case 'w': case 'W': *size = RC_MEMSIZE_24_BITS; break;
     72       case 'g': case 'G': *size = RC_MEMSIZE_32_BITS_BE; break;
     73       case 'i': case 'I': *size = RC_MEMSIZE_16_BITS_BE; break;
     74       case 'j': case 'J': *size = RC_MEMSIZE_24_BITS_BE; break;
     75 
     76       /* case 'v': case 'V': */
     77       /* case 'y': case 'Y': 64 bit? */
     78       /* case 'z': case 'Z': 128 bit? */
     79 
     80       case '0': case '1': case '2': case '3': case '4':
     81       case '5': case '6': case '7': case '8': case '9':
     82       case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
     83       case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
     84         /* legacy support - addresses without a size prefix are assumed to be 16-bit */
     85         aux--;
     86         *size = RC_MEMSIZE_16_BITS;
     87         break;
     88 
     89       default:
     90         return RC_INVALID_MEMORY_OPERAND;
     91     }
     92   }
     93   else if (aux[0] == 'f' || aux[0] == 'F') {
     94     ++aux;
     95     switch (*aux++) {
     96       case 'f': case 'F': *size = RC_MEMSIZE_FLOAT; break;
     97       case 'b': case 'B': *size = RC_MEMSIZE_FLOAT_BE; break;
     98       case 'h': case 'H': *size = RC_MEMSIZE_DOUBLE32; break;
     99       case 'i': case 'I': *size = RC_MEMSIZE_DOUBLE32_BE; break;
    100       case 'm': case 'M': *size = RC_MEMSIZE_MBF32; break;
    101       case 'l': case 'L': *size = RC_MEMSIZE_MBF32_LE; break;
    102 
    103       default:
    104         return RC_INVALID_FP_OPERAND;
    105     }
    106   }
    107   else {
    108     return RC_INVALID_MEMORY_OPERAND;
    109   }
    110 
    111   value = strtoul(aux, &end, 16);
    112 
    113   if (end == aux)
    114     return RC_INVALID_MEMORY_OPERAND;
    115 
    116   if (value > 0xffffffffU)
    117     value = 0xffffffffU;
    118 
    119   *address = (uint32_t)value;
    120   *memaddr = end;
    121   return RC_OK;
    122 }
    123 
    124 static float rc_build_float(uint32_t mantissa_bits, int32_t exponent, int sign) {
    125   /* 32-bit float has a 23-bit mantissa and 8-bit exponent */
    126   const uint32_t implied_bit = 1 << 23;
    127   const uint32_t mantissa = mantissa_bits | implied_bit;
    128   double dbl = ((double)mantissa) / ((double)implied_bit);
    129 
    130   if (exponent > 127) {
    131     /* exponent above 127 is a special number */
    132     if (mantissa_bits == 0) {
    133       /* infinity */
    134 #ifdef INFINITY /* INFINITY and NAN #defines require C99 */
    135       dbl = INFINITY;
    136 #else
    137       dbl = -log(0.0);
    138 #endif
    139     }
    140     else {
    141       /* NaN */
    142 #ifdef NAN
    143       dbl = NAN;
    144 #else
    145       dbl = -sqrt(-1);
    146 #endif
    147     }
    148   }
    149   else if (exponent > 0) {
    150     /* exponent from 1 to 127 is a number greater than 1 */
    151     while (exponent > 30) {
    152       dbl *= (double)(1 << 30);
    153       exponent -= 30;
    154     }
    155     dbl *= (double)((long long)1 << exponent);
    156   }
    157   else if (exponent < 0) {
    158     /* exponent from -1 to -127 is a number less than 1 */
    159 
    160     if (exponent == -127) {
    161       /* exponent -127 (all exponent bits were zero) is a denormalized value
    162        * (no implied leading bit) with exponent -126 */
    163       dbl = ((double)mantissa_bits) / ((double)implied_bit);
    164       exponent = 126;
    165     } else {
    166       exponent = -exponent;
    167     }
    168 
    169     while (exponent > 30) {
    170       dbl /= (double)(1 << 30);
    171       exponent -= 30;
    172     }
    173     dbl /= (double)((long long)1 << exponent);
    174   }
    175   else {
    176     /* exponent of 0 requires no adjustment */
    177   }
    178 
    179   return (sign) ? (float)-dbl : (float)dbl;
    180 }
    181 
    182 static void rc_transform_memref_float(rc_typed_value_t* value) {
    183   /* decodes an IEEE 754 float */
    184   const uint32_t mantissa = (value->value.u32 & 0x7FFFFF);
    185   const int32_t exponent = (int32_t)((value->value.u32 >> 23) & 0xFF) - 127;
    186   const int sign = (value->value.u32 & 0x80000000);
    187   value->value.f32 = rc_build_float(mantissa, exponent, sign);
    188   value->type = RC_VALUE_TYPE_FLOAT;
    189 }
    190 
    191 static void rc_transform_memref_float_be(rc_typed_value_t* value) {
    192   /* decodes an IEEE 754 float in big endian format */
    193   const uint32_t mantissa = ((value->value.u32 & 0xFF000000) >> 24) |
    194                             ((value->value.u32 & 0x00FF0000) >> 8) |
    195                             ((value->value.u32 & 0x00007F00) << 8);
    196   const int32_t exponent = (int32_t)(((value->value.u32 & 0x0000007F) << 1) |
    197                                      ((value->value.u32 & 0x00008000) >> 15)) - 127;
    198   const int sign = (value->value.u32 & 0x00000080);
    199   value->value.f32 = rc_build_float(mantissa, exponent, sign);
    200   value->type = RC_VALUE_TYPE_FLOAT;
    201 }
    202 
    203 static void rc_transform_memref_double32(rc_typed_value_t* value)
    204 {
    205   /* decodes the four most significant bytes of an IEEE 754 double into a float */
    206   const uint32_t mantissa = (value->value.u32 & 0x000FFFFF) << 3;
    207   const int32_t exponent = (int32_t)((value->value.u32 >> 20) & 0x7FF) - 1023;
    208   const int sign = (value->value.u32 & 0x80000000);
    209   value->value.f32 = rc_build_float(mantissa, exponent, sign);
    210   value->type = RC_VALUE_TYPE_FLOAT;
    211 }
    212 
    213 static void rc_transform_memref_double32_be(rc_typed_value_t* value)
    214 {
    215   /* decodes the four most significant bytes of an IEEE 754 double in big endian format into a float */
    216   const uint32_t mantissa = (((value->value.u32 & 0xFF000000) >> 24) |
    217     ((value->value.u32 & 0x00FF0000) >> 8) |
    218     ((value->value.u32 & 0x00000F00) << 8)) << 3;
    219   const int32_t exponent = (int32_t)(((value->value.u32 & 0x0000007F) << 4) |
    220     ((value->value.u32 & 0x0000F000) >> 12)) - 1023;
    221   const int sign = (value->value.u32 & 0x00000080);
    222   value->value.f32 = rc_build_float(mantissa, exponent, sign);
    223   value->type = RC_VALUE_TYPE_FLOAT;
    224 }
    225 
    226 static void rc_transform_memref_mbf32(rc_typed_value_t* value) {
    227   /* decodes a Microsoft Binary Format float */
    228   /* NOTE: 32-bit MBF is stored in memory as big endian (at least for Apple II) */
    229   const uint32_t mantissa = ((value->value.u32 & 0xFF000000) >> 24) |
    230                             ((value->value.u32 & 0x00FF0000) >> 8) |
    231                             ((value->value.u32 & 0x00007F00) << 8);
    232   const int32_t exponent = (int32_t)(value->value.u32 & 0xFF) - 129;
    233   const int sign = (value->value.u32 & 0x00008000);
    234 
    235   if (mantissa == 0 && exponent == -129)
    236     value->value.f32 = (sign) ? -0.0f : 0.0f;
    237   else
    238     value->value.f32 = rc_build_float(mantissa, exponent, sign);
    239 
    240   value->type = RC_VALUE_TYPE_FLOAT;
    241 }
    242 
    243 static void rc_transform_memref_mbf32_le(rc_typed_value_t* value) {
    244   /* decodes a Microsoft Binary Format float */
    245   /* Locomotive BASIC (CPC) uses MBF40, but in little endian format */
    246   const uint32_t mantissa = value->value.u32 & 0x007FFFFF;
    247   const int32_t exponent = (int32_t)(value->value.u32 >> 24) - 129;
    248   const int sign = (value->value.u32 & 0x00800000);
    249 
    250   if (mantissa == 0 && exponent == -129)
    251     value->value.f32 = (sign) ? -0.0f : 0.0f;
    252   else
    253     value->value.f32 = rc_build_float(mantissa, exponent, sign);
    254 
    255   value->type = RC_VALUE_TYPE_FLOAT;
    256 }
    257 
    258 static const uint8_t rc_bits_set[16] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
    259 
    260 void rc_transform_memref_value(rc_typed_value_t* value, uint8_t size) {
    261   /* ASSERT: value->type == RC_VALUE_TYPE_UNSIGNED */
    262   switch (size)
    263   {
    264     case RC_MEMSIZE_8_BITS:
    265       value->value.u32 = (value->value.u32 & 0x000000ff);
    266       break;
    267 
    268     case RC_MEMSIZE_16_BITS:
    269       value->value.u32 = (value->value.u32 & 0x0000ffff);
    270       break;
    271 
    272     case RC_MEMSIZE_24_BITS:
    273       value->value.u32 = (value->value.u32 & 0x00ffffff);
    274       break;
    275 
    276     case RC_MEMSIZE_32_BITS:
    277       break;
    278 
    279     case RC_MEMSIZE_BIT_0:
    280       value->value.u32 = (value->value.u32 >> 0) & 1;
    281       break;
    282 
    283     case RC_MEMSIZE_BIT_1:
    284       value->value.u32 = (value->value.u32 >> 1) & 1;
    285       break;
    286 
    287     case RC_MEMSIZE_BIT_2:
    288       value->value.u32 = (value->value.u32 >> 2) & 1;
    289       break;
    290 
    291     case RC_MEMSIZE_BIT_3:
    292       value->value.u32 = (value->value.u32 >> 3) & 1;
    293       break;
    294 
    295     case RC_MEMSIZE_BIT_4:
    296       value->value.u32 = (value->value.u32 >> 4) & 1;
    297       break;
    298 
    299     case RC_MEMSIZE_BIT_5:
    300       value->value.u32 = (value->value.u32 >> 5) & 1;
    301       break;
    302 
    303     case RC_MEMSIZE_BIT_6:
    304       value->value.u32 = (value->value.u32 >> 6) & 1;
    305       break;
    306 
    307     case RC_MEMSIZE_BIT_7:
    308       value->value.u32 = (value->value.u32 >> 7) & 1;
    309       break;
    310 
    311     case RC_MEMSIZE_LOW:
    312       value->value.u32 = value->value.u32 & 0x0f;
    313       break;
    314 
    315     case RC_MEMSIZE_HIGH:
    316       value->value.u32 = (value->value.u32 >> 4) & 0x0f;
    317       break;
    318 
    319     case RC_MEMSIZE_BITCOUNT:
    320       value->value.u32 = rc_bits_set[(value->value.u32 & 0x0F)]
    321                        + rc_bits_set[((value->value.u32 >> 4) & 0x0F)];
    322       break;
    323 
    324     case RC_MEMSIZE_16_BITS_BE:
    325       value->value.u32 = ((value->value.u32 & 0xFF00) >> 8) |
    326                          ((value->value.u32 & 0x00FF) << 8);
    327       break;
    328 
    329     case RC_MEMSIZE_24_BITS_BE:
    330       value->value.u32 = ((value->value.u32 & 0xFF0000) >> 16) |
    331                           (value->value.u32 & 0x00FF00) |
    332                          ((value->value.u32 & 0x0000FF) << 16);
    333       break;
    334 
    335     case RC_MEMSIZE_32_BITS_BE:
    336       value->value.u32 = ((value->value.u32 & 0xFF000000) >> 24) |
    337                          ((value->value.u32 & 0x00FF0000) >> 8) |
    338                          ((value->value.u32 & 0x0000FF00) << 8) |
    339                          ((value->value.u32 & 0x000000FF) << 24);
    340       break;
    341 
    342     case RC_MEMSIZE_FLOAT:
    343       rc_transform_memref_float(value);
    344       break;
    345 
    346     case RC_MEMSIZE_FLOAT_BE:
    347       rc_transform_memref_float_be(value);
    348       break;
    349 
    350     case RC_MEMSIZE_DOUBLE32:
    351       rc_transform_memref_double32(value);
    352       break;
    353 
    354     case RC_MEMSIZE_DOUBLE32_BE:
    355       rc_transform_memref_double32_be(value);
    356       break;
    357 
    358     case RC_MEMSIZE_MBF32:
    359       rc_transform_memref_mbf32(value);
    360       break;
    361 
    362     case RC_MEMSIZE_MBF32_LE:
    363       rc_transform_memref_mbf32_le(value);
    364       break;
    365 
    366     default:
    367       break;
    368   }
    369 }
    370 
    371 static const uint32_t rc_memref_masks[] = {
    372   0x000000ff, /* RC_MEMSIZE_8_BITS     */
    373   0x0000ffff, /* RC_MEMSIZE_16_BITS    */
    374   0x00ffffff, /* RC_MEMSIZE_24_BITS    */
    375   0xffffffff, /* RC_MEMSIZE_32_BITS    */
    376   0x0000000f, /* RC_MEMSIZE_LOW        */
    377   0x000000f0, /* RC_MEMSIZE_HIGH       */
    378   0x00000001, /* RC_MEMSIZE_BIT_0      */
    379   0x00000002, /* RC_MEMSIZE_BIT_1      */
    380   0x00000004, /* RC_MEMSIZE_BIT_2      */
    381   0x00000008, /* RC_MEMSIZE_BIT_3      */
    382   0x00000010, /* RC_MEMSIZE_BIT_4      */
    383   0x00000020, /* RC_MEMSIZE_BIT_5      */
    384   0x00000040, /* RC_MEMSIZE_BIT_6      */
    385   0x00000080, /* RC_MEMSIZE_BIT_7      */
    386   0x000000ff, /* RC_MEMSIZE_BITCOUNT   */
    387   0x0000ffff, /* RC_MEMSIZE_16_BITS_BE */
    388   0x00ffffff, /* RC_MEMSIZE_24_BITS_BE */
    389   0xffffffff, /* RC_MEMSIZE_32_BITS_BE */
    390   0xffffffff, /* RC_MEMSIZE_FLOAT      */
    391   0xffffffff, /* RC_MEMSIZE_MBF32      */
    392   0xffffffff, /* RC_MEMSIZE_MBF32_LE   */
    393   0xffffffff, /* RC_MEMSIZE_FLOAT_BE   */
    394   0xffffffff, /* RC_MEMSIZE_DOUBLE32   */
    395   0xffffffff, /* RC_MEMSIZE_DOUBLE32_BE*/
    396   0xffffffff  /* RC_MEMSIZE_VARIABLE   */
    397 };
    398 
    399 uint32_t rc_memref_mask(uint8_t size) {
    400   const size_t index = (size_t)size;
    401   if (index >= sizeof(rc_memref_masks) / sizeof(rc_memref_masks[0]))
    402     return 0xffffffff;
    403 
    404   return rc_memref_masks[index];
    405 }
    406 
    407 /* all sizes less than 8-bits (1 byte) are mapped to 8-bits. 24-bit is mapped to 32-bit
    408  * as we don't expect the client to understand a request for 3 bytes. all other reads are
    409  * mapped to the little-endian read of the same size. */
    410 static const uint8_t rc_memref_shared_sizes[] = {
    411   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_8_BITS     */
    412   RC_MEMSIZE_16_BITS, /* RC_MEMSIZE_16_BITS    */
    413   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_24_BITS    */
    414   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_32_BITS    */
    415   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_LOW        */
    416   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_HIGH       */
    417   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BIT_0      */
    418   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BIT_1      */
    419   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BIT_2      */
    420   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BIT_3      */
    421   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BIT_4      */
    422   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BIT_5      */
    423   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BIT_6      */
    424   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BIT_7      */
    425   RC_MEMSIZE_8_BITS,  /* RC_MEMSIZE_BITCOUNT   */
    426   RC_MEMSIZE_16_BITS, /* RC_MEMSIZE_16_BITS_BE */
    427   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_24_BITS_BE */
    428   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_32_BITS_BE */
    429   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_FLOAT      */
    430   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_MBF32      */
    431   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_MBF32_LE   */
    432   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_FLOAT_BE   */
    433   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_DOUBLE32   */
    434   RC_MEMSIZE_32_BITS, /* RC_MEMSIZE_DOUBLE32_BE*/
    435   RC_MEMSIZE_32_BITS  /* RC_MEMSIZE_VARIABLE   */
    436 };
    437 
    438 uint8_t rc_memref_shared_size(uint8_t size) {
    439   const size_t index = (size_t)size;
    440   if (index >= sizeof(rc_memref_shared_sizes) / sizeof(rc_memref_shared_sizes[0]))
    441     return size;
    442 
    443   return rc_memref_shared_sizes[index];
    444 }
    445 
    446 uint32_t rc_peek_value(uint32_t address, uint8_t size, rc_peek_t peek, void* ud) {
    447   if (!peek)
    448     return 0;
    449 
    450   switch (size)
    451   {
    452     case RC_MEMSIZE_8_BITS:
    453       return peek(address, 1, ud);
    454 
    455     case RC_MEMSIZE_16_BITS:
    456       return peek(address, 2, ud);
    457 
    458     case RC_MEMSIZE_32_BITS:
    459       return peek(address, 4, ud);
    460 
    461     default:
    462     {
    463       uint32_t value;
    464       const size_t index = (size_t)size;
    465       if (index >= sizeof(rc_memref_shared_sizes) / sizeof(rc_memref_shared_sizes[0]))
    466         return 0;
    467 
    468       /* fetch the larger value and mask off the bits associated to the specified size
    469        * for correct deduction of prior value. non-prior memrefs should already be using
    470        * shared size memrefs to minimize the total number of memory reads required. */
    471       value = rc_peek_value(address, rc_memref_shared_sizes[index], peek, ud);
    472       return value & rc_memref_masks[index];
    473     }
    474   }
    475 }
    476 
    477 void rc_update_memref_value(rc_memref_value_t* memref, uint32_t new_value) {
    478   if (memref->value == new_value) {
    479     memref->changed = 0;
    480   }
    481   else {
    482     memref->prior = memref->value;
    483     memref->value = new_value;
    484     memref->changed = 1;
    485   }
    486 }
    487 
    488 void rc_update_memref_values(rc_memref_t* memref, rc_peek_t peek, void* ud) {
    489   while (memref) {
    490     /* indirect memory references are not shared and will be updated in rc_get_memref_value */
    491     if (!memref->value.is_indirect)
    492       rc_update_memref_value(&memref->value, rc_peek_value(memref->address, memref->value.size, peek, ud));
    493 
    494     memref = memref->next;
    495   }
    496 }
    497 
    498 void rc_init_parse_state_memrefs(rc_parse_state_t* parse, rc_memref_t** memrefs) {
    499   parse->first_memref = memrefs;
    500   *memrefs = 0;
    501 }
    502 
    503 static uint32_t rc_get_memref_value_value(const rc_memref_value_t* memref, int operand_type) {
    504   switch (operand_type)
    505   {
    506     /* most common case explicitly first, even though it could be handled by default case.
    507      * this helps the compiler to optimize if it turns the switch into a series of if/elses */
    508     case RC_OPERAND_ADDRESS:
    509       return memref->value;
    510 
    511     case RC_OPERAND_DELTA:
    512       if (!memref->changed) {
    513         /* fallthrough */
    514     default:
    515         return memref->value;
    516       }
    517       /* fallthrough */
    518     case RC_OPERAND_PRIOR:
    519       return memref->prior;
    520   }
    521 }
    522 
    523 uint32_t rc_get_memref_value(rc_memref_t* memref, int operand_type, rc_eval_state_t* eval_state) {
    524   /* if this is an indirect reference, handle the indirection. */
    525   if (memref->value.is_indirect) {
    526     const uint32_t new_address = memref->address + eval_state->add_address;
    527     rc_update_memref_value(&memref->value, rc_peek_value(new_address, memref->value.size, eval_state->peek, eval_state->peek_userdata));
    528   }
    529 
    530   return rc_get_memref_value_value(&memref->value, operand_type);
    531 }