1

Hello I can’t figure out why in the add instruction I need to and by 7 this is the cpp code for the Add instruction

uint16_t dr = (instr >> 9) & 0b111;
                uint16_t sr1 = (instr >> 6) & 0b111;
                uint16_t sr2 = instr & 0b111;

                uint16_t second = registers[sr2];
                uint16_t immediateFlag = (instr >> 5) & 0b1;
                if (immediateFlag) {
                    uint16_t imm5 = instr & 0b11111;
                    second = signExtend(imm5, 5);
                }

                registers[dr] = registers[sr1] + second;

all the lines anded with 7 are the parts I don’t get. This is how the instruction looks like:

  • bits 15-12 opcode(0001)
  • bits 11-9 destination register
  • bits 8-6 source1
  • bits 5 0 or 1 (immediate mode)
  • bits 4-3 nothing
  • bits 2-0 source2

How does this 0b111 (7 in decimal) come into play and why?

  • When extracting a bitfield from a word (an instruction here), you want it alone, and right justified, so that makes it a normal number you can use to index an array for example. The mask could have gone first, then the shift, but that makes the mask numerically larger, so this order is usually preferred. Alternatively, the word can be shifted left then right; that will also isolate the bits of interest leaving the value right justified. The shift left first approach also allows for sign extension by following with arithmetic right shift. – Erik Eidt Dec 22 '21 at 16:36

1 Answers1

4

Take a look at the first line of code: it tries to decode the destination register, which is in bits 9-11 of your input number.

Assuming instr has 16 bits abcdefgh ijklmnop, then we want to extract bits 9-11, which is efg:
instr >> 9 shifts everything to the right by 9 bits, but the answer still has 16 bits: 00000000 0abcdefg.
& 0b111 is a shorthand for & 0b00000000 00000111, so applying that to instr >> 9 results in 00000000 00000efg, or exactly the three bits we were hoping to extract.

Botje
  • 26,269
  • 3
  • 31
  • 41