All pastes #424560 Raw Edit

arm load imm 32bit

public c v1 · immutable
·published 2007-04-04 21:24 UTC
rendered paste body
u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations){  u32 store_count = 0;  u32 left_shift = 0;  u32 i;  // Otherwise it'll return 0 things to store because it'll never  // find anything.  if(imm == 0)  {    rotations[0] = 0;    stores[0] = 0;    return 1;  }  // Find chunks of non-zero data at 2 bit alignments.  while(1)  {    for(; left_shift < 32; left_shift += 2)    {      if((imm >> left_shift) & 0x03)        break;    }    if(left_shift == 32)    {      // We've hit the end of the useful data.      return store_count;    }    // Hit the end, it might wrap back around to the beginning.    if(left_shift >= 24)    {      // Make a mask for the residual bits. IE, if we have      // 5 bits of data at the end we can wrap around to 3      // bits of data in the beginning. Thus the first      // thing, after being shifted left, has to be less      // than 111b, 0x7, or (1 << 3) - 1.      u32 top_bits = 32 - left_shift;      u32 residual_bits = 8 - top_bits;      u32 residual_mask = (1 << residual_bits) - 1;      if((store_count > 1) && (left_shift > 24) &&       ((stores[0] << ((32 - rotations[0]) & 0x1F)) < residual_mask))      {        // Then we can throw out the last bit and tack it on        // to the first bit.        u32 initial_bits = rotations[0];        stores[0] =         (stores[0] << ((top_bits + (32 - rotations[0])) & 0x1F)) |         ((imm >> left_shift) & 0xFF);        rotations[0] = top_bits;        return store_count;      }      else      {        // There's nothing to wrap over to in the beginning        stores[store_count] = (imm >> left_shift) & 0xFF;        rotations[store_count] = (32 - left_shift) & 0x1F;        return store_count + 1;      }      break;    }    stores[store_count] = (imm >> left_shift) & 0xFF;    rotations[store_count] = (32 - left_shift) & 0x1F;    store_count++;    left_shift += 8;  }}#define arm_load_imm_32bit(ireg, imm)                                         \{                                                                             \  u32 stores[4];                                                              \  u32 rotations[4];                                                           \  u32 store_count = arm_disect_imm_32bit(imm, stores, rotations);             \  u32 i;                                                                      \                                                                              \  ARM_MOV_REG_IMM(0, ireg, stores[0], rotations[0]);                          \                                                                              \  for(i = 1; i < store_count; i++)                                            \  {                                                                           \    ARM_ORR_REG_IMM(0, ireg, ireg, stores[i], rotations[i]);                  \  }                                                                           \}                                                                             \