[ create a new paste ] login | about

Link: http://codepad.org/a8uewrxX    [ raw code | output | fork ]

AaronMiller - C, pasted on Feb 23:
/*
When selecting between two values without branching (e.g., in a virtual machine),
you can use a specific bit (or bit pattern) to select between the two values, like
so:

  int a, b; -- a = value 0, b = value 1
  int instr; -- the instruction
  int v; -- v is the resulting value
  v = (a&(-((instr & (1<<bit_id))>>bit_id))) | (b&(-((~instr & (1<<bit_id))>>bit_id)));

  --------------------------------------------------------

  a = 1101
  b = 0110
  instr = 0100

  instr & (1<<2) = 0100 & 4 = 0100 & 0100 = 0100
  0100 >> 2 = 0001
  -0001 = 1111

  ~instr & (1<<2) = 1011 & 4 = 1011 & 0100 = 0000
  0000 >> 2 = 0000
  -0000 = 0000

  a&1111 | b&0000 = 1101&1111 | 0110&0000 = 1101 | 0000 = 1101
*/

int selectfrombit(int instr, int bit_id, int a, int b) {
  return (a&(-((instr & (1<<bit_id))>>bit_id))) | (b&(-((~instr & (1<<bit_id))>>bit_id)));
}

void selectfrombit_test(int instr, int bit_id, int a, int b) {
  printf("selectfrombit(%i, %i, %i, %i) = %i\n", instr, bit_id, a, b, selectfrombit(instr, bit_id, a, b));
}

int main() {
  selectfrombit_test(4, 2, 42, 23);
  selectfrombit_test(8, 2, 42, 23);
  selectfrombit_test(2, 2, 20, 30);
  selectfrombit_test(2, 1, 20, 30);
  selectfrombit_test(2, 0, 20, 30);

  return 0;
}


Output:
1
2
3
4
5
selectfrombit(4, 2, 42, 23) = 42
selectfrombit(8, 2, 42, 23) = 23
selectfrombit(2, 2, 20, 30) = 30
selectfrombit(2, 1, 20, 30) = 20
selectfrombit(2, 0, 20, 30) = 30


Create a new paste based on this one


Comments: