0

I have a final 32 bit integer

int32_t final;

It has this format

6 bits   5 bits   5 bits   5 bits   5 bits   6 bits
opcode   rs       rt       rd       shamt    funct

I have opcode populated with 0. I have rs rt and rd populated with their respective integers. shamt has its value and so does funct. My only issue is, how do I load these into the final int? I know it has something to do with the << operator and logic like & and |. I have this function

unsigned mask(unsigned a, unsigned b)
{
   unsigned r = 0;
   unsigned i;
   for (i=a; i<=b; i++)
       r |= 1 << i;

   return r;
}

which creates a mask that can be anded with a value to get it's bits a-b. Am I on the right track here?

3 Answers3

4

Though I find Stargateur's solution based on bitfields very elegant, here a solution based on "ordinary" left shifts: Note that data type is unsigned rather than signed:

uint32_t final;

int opcode = 0;
int rs = 10;
int rt = 20;
int rd = 11;
int shamt = 12;
int funct = 11;

final = opcode;
final <<= 5; final |= rs;
final <<= 5; final |= rt;
final <<= 5 ;final |= rd;
final <<= 5; final |= shamt;
final <<= 6; final |= funct;

printf("0x%08x", final);
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
3

You could use a bit field:

union foo {
  uint32_t header;
  struct {
    uint32_t opcode : 6,
             rs : 5,
             rt : 5,
             rd : 5,
             shamt : 5,
             funct : 6;
  };
};

Example:

int main(void)
{
    union foo foo;

    foo.opcode = 5;
    foo.rs = 0;
    foo.rt = 0;
    foo.rd = 0;
    foo.shamt = 0;
    foo.funct = 5;
    printf("%x\n", foo.header);
}

Note: This doesn't handle endianness and this is implementation behavior https://stackoverflow.com/a/6044223/7076153. If you want to be portable use bit-wise.

Community
  • 1
  • 1
Stargateur
  • 24,473
  • 8
  • 65
  • 91
0

You can perhaps have something like:

int32_t constructFinal (unsigned opcode, unsigned rs, unsigned rt, unsigned rd, unsigned shamt, unsigned funct) {
  unsigned final = ((opcode & 0x3F) << 26) |
    ((rs & 0x1F) << 21) |
    ((rt & 0x1F) << 16) |
    ((rd & 0x1F) << 11) |
    ((shamt & 0x1F) << 6) |
    (funct & 0x3F);
  return (int32_t)final;
}
Winestone
  • 1,500
  • 9
  • 19