Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char...

85
1

Transcript of Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char...

Page 1: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

1

Page 2: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

Changelog

Changes made in this version not seen in first lecture:12 September 2017: slide 28, 33: quote solution that uses z correctly

1

Page 3: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

last time

Y86 — choices, encoding and decoding

shift operatorsshr assembly, >> in Cright shift = towards least significant bitright shift = dividing by power of two

2

Page 4: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

on the quizzes in general

yes, I know quizzes are hard

intention: quiz questions from slides/etc. + some serious thought

(and sometimes I miss the mark)

main purpose: review material other than before exams, warningsign for me

why graded? because otherwise…

3

Page 5: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

on the quiz (1)

RISC versus CISC: about simplifying hardware

variable-length encoding is less simple for HW

instructions chosen more based on what’s simple for HW(e.g. push/pop not simple for HW)

more registers — simpler than adding more instructionscompensates for seperate memory instructions

4

Page 6: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

on the quiz (2)

instruction set — what the instructions do

size of memory address — operands to rmmovq, etc. mean what?

floating point support — do such instructions exist?

5

Page 7: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

constructing instructions

typedef unsigned char byte;byte make_simple_opcode(byte icode) {

// function code is fixed as 0 for nowreturn opcode * 16;// 16 = 1 0000 in binary

}

6

Page 8: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

constructing instructions in hardware

icode

0 0 0 0

opcode

7

Page 9: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

reversed shift right?

((((((((((((hhhhhhhhhhhhshr $-4, %reg

(((((((((((((hhhhhhhhhhhhhopcode >> (-4)

8

Page 10: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

shift left

x86 instruction: shl — shift leftC: value << amount

shl $amount, %reg (or variable: shr %cl, %reg)%reg (initial value)

%reg (final value)

1 0 1 1 0

0

0

0

1

1

0

0

1

1

0

0

0

0

0

0

0

0

0

0

0

0

9

Page 11: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

shift left

x86 instruction: shl — shift leftC: value << amount

shl $amount, %reg (or variable: shr %cl, %reg)%reg (initial value)

%reg (final value)

1 0 1 1 0

0

0

0

1

1

0

0

1

1

0

0

0

0

0

0

0

0

0

0

0

0

9

Page 12: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

left shift in math1 << 0 == 1 0000 00011 << 1 == 2 0000 00101 << 2 == 4 0000 0100

10 << 0 == 10 0000 101010 << 1 == 20 0001 010010 << 2 == 40 0010 1000

x << y = x × 2y

10

Page 13: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

left shift in math1 << 0 == 1 0000 00011 << 1 == 2 0000 00101 << 2 == 4 0000 0100

10 << 0 == 10 0000 101010 << 1 == 20 0001 010010 << 2 == 40 0010 1000

x << y = x × 2y

10

Page 14: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

extracting icode from more

11111000 0 0 1 0 0 0 0 0icode ifunrBrA

// % -- remainderunsigned extract_opcode1(unsigned value) {

return (value / 16) % 16;}

unsigned extract_opcode2(unsigned value) {return (value % 256) / 16;

}

11

Page 15: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

extracting icode from more

11111000 0 0 1 0 0 0 0 0icode ifunrBrA

// % -- remainderunsigned extract_opcode1(unsigned value) {

return (value / 16) % 16;}

unsigned extract_opcode2(unsigned value) {return (value % 256) / 16;

} 11

Page 16: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

manipulating bits?

easy to manipulate individual bits in HW

how do we expose that to software?

12

Page 17: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

interlude: a truth table

AND 0 10 0 01 0 1

AND with 1: keep a bit the same

AND with 0: clear a bit

method: construct “mask” of what to keep/remove

13

Page 18: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

interlude: a truth table

AND 0 10 0 01 0 1

AND with 1: keep a bit the same

AND with 0: clear a bit

method: construct “mask” of what to keep/remove

13

Page 19: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

interlude: a truth table

AND 0 10 0 01 0 1

AND with 1: keep a bit the same

AND with 0: clear a bit

method: construct “mask” of what to keep/remove

13

Page 20: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

interlude: a truth table

AND 0 10 0 01 0 1

AND with 1: keep a bit the same

AND with 0: clear a bit

method: construct “mask” of what to keep/remove

13

Page 21: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

bitwise AND — &

Treat value as array of bits

1 & 1 == 1

1 & 0 == 0

0 & 0 == 0

2 & 4 == 0

10 & 7 == 2

… 0 0 1 0& … 0 1 0 0

… 0 0 0 0

… 1 0 1 0& … 0 1 1 1

… 0 0 1 0

14

Page 22: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

bitwise AND — &

Treat value as array of bits

1 & 1 == 1

1 & 0 == 0

0 & 0 == 0

2 & 4 == 0

10 & 7 == 2

… 0 0 1 0& … 0 1 0 0

… 0 0 0 0

… 1 0 1 0& … 0 1 1 1

… 0 0 1 0

14

Page 23: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

bitwise AND — &

Treat value as array of bits

1 & 1 == 1

1 & 0 == 0

0 & 0 == 0

2 & 4 == 0

10 & 7 == 2

… 0 0 1 0& … 0 1 0 0

… 0 0 0 0

… 1 0 1 0& … 0 1 1 1

… 0 0 1 0

14

Page 24: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

bitwise AND — C/assembly

x86: and %reg, %reg

C: foo & bar

15

Page 25: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

bitwise hardware (10 & 7 == 2)

10 7

...

0101 1110

0100

16

Page 26: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

extract opcode from larger

unsigned extract_opcode1_bitwise(unsigned value) {return (value >> 4) & 0xF; // 0xF: 00001111// like (value / 16) % 16

}

unsigned extract_opcode2_bitwise(unsigned value) {return (value & 0xF0) >> 4; // 0xF0: 11110000// like (value % 256) / 16;

}

17

Page 27: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

extract opcode from larger

extract_opcode1_bitwise:movl %edi, %eaxshrl $4, %eaxandl $0xF, %eaxret

extract_opcode2_bitwise:movl %edi, %eaxandl $0xF0, %eaxshrl $4, %eaxret

18

Page 28: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

more truth tables

AND 0 10 0 01 0 1

OR 0 10 0 11 1 1

XOR 0 10 0 11 1 0

&

conditionally clear bitconditionally keep bit

|

conditionally set bit

^

conditionally flip bit

19

Page 29: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

bitwise OR — |

1 | 1 == 1

1 | 0 == 1

0 | 0 == 0

2 | 4 == 6

10 | 7 == 15

… 1 0 1 0| … 0 1 1 1

… 1 1 1 1

20

Page 30: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

bitwise xor — ̂

1 ^ 1 == 0

1 ^ 0 == 1

0 ^ 0 == 0

2 ^ 4 == 6

10 ^ 7 == 13

… 1 0 1 0^ … 0 1 1 1

… 1 1 0 1

21

Page 31: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

negation / not — ~

~ (‘complement’) is bitwise version of !:

!0 == 1

!notZero == 0

~0 == (int) 0xFFFFFFFF (aka −1)

~2 == (int) 0xFFFFFFFD (aka −3)

~((unsigned) 2) == 0xFFFFFFFD

~ 0 0 … 0 0 0 01 1 … 1 1 1 1

32 bits

22

Page 32: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

negation / not — ~

~ (‘complement’) is bitwise version of !:

!0 == 1

!notZero == 0

~0 == (int) 0xFFFFFFFF (aka −1)

~2 == (int) 0xFFFFFFFD (aka −3)

~((unsigned) 2) == 0xFFFFFFFD

~ 0 0 … 0 0 0 01 1 … 1 1 1 1

32 bits

22

Page 33: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

negation / not — ~

~ (‘complement’) is bitwise version of !:

!0 == 1

!notZero == 0

~0 == (int) 0xFFFFFFFF (aka −1)

~2 == (int) 0xFFFFFFFD (aka −3)

~((unsigned) 2) == 0xFFFFFFFD

~ 0 0 … 0 0 0 01 1 … 1 1 1 1

32 bits

22

Page 34: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

note: ternary operator

w = (x ? y : z)

if (x) { w = y; } else { w = z; }

23

Page 35: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

one-bit ternary

(x ? y : z)

constraint: everything is 0 or 1

now: reimplement in C without if/else/||/etc.(assembly: no jumps probably)

divide-and-conquer:(x ? y : 0)(x ? 0 : z)

24

Page 36: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

one-bit ternary

(x ? y : z)

constraint: everything is 0 or 1

now: reimplement in C without if/else/||/etc.(assembly: no jumps probably)

divide-and-conquer:(x ? y : 0)(x ? 0 : z)

24

Page 37: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

one-bit ternary parts (1)

constraint: everything is 0 or 1

(x ? y : 0)

y=0 y=1x=0 0 0x=1 0 1

→ (x & y)

25

Page 38: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

one-bit ternary parts (1)

constraint: everything is 0 or 1

(x ? y : 0)

y=0 y=1x=0 0 0x=1 0 1

→ (x & y)

25

Page 39: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

one-bit ternary parts (2)

(x ? y : 0) = (x & y)

(x ? 0 : z)

opposite x: ~x

((~x) & z)

26

Page 40: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

one-bit ternary parts (2)

(x ? y : 0) = (x & y)

(x ? 0 : z)

opposite x: ~x

((~x) & z)

26

Page 41: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

one-bit ternary

constraint: everything is 0 or 1 — but y, z is any integer

(x ? y : z)

(x ? y : 0) | (x ? 0 : z)

(x & y) | ((~x) & z)

27

Page 42: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

multibit ternary

constraint: x is 0 or 1

old solution ((x & y) | (~x) & 1) only gets least sig. bit

(x ? y : z)

(x ? y : 0) | (x ? 0 : z)

((−x) & y) | ((−(x ^ 1)) & z)

28

Page 43: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

multibit ternary

constraint: x is 0 or 1

old solution ((x & y) | (~x) & 1) only gets least sig. bit

(x ? y : z)

(x ? y : 0) | (x ? 0 : z)

((−x) & y) | ((−(x ^ 1)) & z)

28

Page 44: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

constructing masks

constraint: x is 0 or 1

(x ? y : 0)

if x = 1: want 1111111111…1 (keep y)

if x = 0: want 0000000000…0 (want 0)

one idea: x | (x << 1) | (x << 2) | ...

a trick: −x

((-x) & y)

29

Page 45: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

constructing masks

constraint: x is 0 or 1

(x ? y : 0)

if x = 1: want 1111111111…1 (keep y)

if x = 0: want 0000000000…0 (want 0)

one idea: x | (x << 1) | (x << 2) | ...

a trick: −x

((-x) & y)

29

Page 46: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

two’s complement refresher

1−231

1+230

1+229

… 1+22

1+21

1+20

−1 =

−10

1

231 − 1−231

−231 + 10111 1111… 1111

1000 0000… 0000

1111 1111… 1111

30

Page 47: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

two’s complement refresher

1−231

1+230

1+229

… 1+22

1+21

1+20

−1 =

−10

1

231 − 1−231

−231 + 1

0111 1111… 1111

1000 0000… 0000

1111 1111… 1111

30

Page 48: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

two’s complement refresher

1−231

1+230

1+229

… 1+22

1+21

1+20

−1 =

−10

1

231 − 1−231

−231 + 10111 1111… 1111

1000 0000… 0000

1111 1111… 1111

30

Page 49: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

constructing masks

constraint: x is 0 or 1

(x ? y : 0)

if x = 1: want 1111111111…1 (keep y)

if x = 0: want 0000000000…0 (want 0)

one idea: x | (x << 1) | (x << 2) | ...

a trick: −x

((-x) & y)31

Page 50: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

constructing other masks

constraint: x is 0 or 1

(x ? 0 : z)

if x = ��SS1 0: want 1111111111…1

if x = ��AA0 1: want 0000000000…0

mask: ��HH-x

−(x^1)

32

Page 51: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

constructing other masks

constraint: x is 0 or 1

(x ? 0 : z)

if x = ��SS1 0: want 1111111111…1

if x = ��AA0 1: want 0000000000…0

mask: ��HH-x −(x^1)

32

Page 52: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

multibit ternary

constraint: x is 0 or 1

old solution ((x & y) | (~x) & 1) only gets least sig. bit

(x ? y : z)

(x ? y : 0) | (x ? 0 : z)

((−x) & y) | ((−(x ^ 1)) & z)

33

Page 53: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

fully multibit

((((((((((((((hhhhhhhhhhhhhhconstraint: x is 0 or 1

(x ? y : z)

easy C way: !x = 0 or 1, !!x = 0 or 1x86 assembly: testq %rax, %rax then sete/setne(copy from ZF)

(x ? y : 0) | (x ? 0 : z)

((−!!x) & y) | ((−!x) & z)

34

Page 54: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

fully multibit

((((((((((((((hhhhhhhhhhhhhhconstraint: x is 0 or 1

(x ? y : z)

easy C way: !x = 0 or 1, !!x = 0 or 1x86 assembly: testq %rax, %rax then sete/setne(copy from ZF)

(x ? y : 0) | (x ? 0 : z)

((−!!x) & y) | ((−!x) & z)

34

Page 55: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

fully multibit

((((((((((((((hhhhhhhhhhhhhhconstraint: x is 0 or 1

(x ? y : z)

easy C way: !x = 0 or 1, !!x = 0 or 1x86 assembly: testq %rax, %rax then sete/setne(copy from ZF)

(x ? y : 0) | (x ? 0 : z)

((−!!x) & y) | ((−!x) & z)

34

Page 56: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

simple operation performance

typical modern desktop processor:bitwise and/or/xor, shift, add, subtract, compare — ∼ 1 cycleinteger multiply — ∼ 1-3 cyclesinteger divide — ∼ 10-150 cycles

(smaller/simpler/lower-power processors are different)

add/subtract/compare are more complicated in hardware!

but much more important for typical applications

35

Page 57: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

simple operation performance

typical modern desktop processor:bitwise and/or/xor, shift, add, subtract, compare — ∼ 1 cycleinteger multiply — ∼ 1-3 cyclesinteger divide — ∼ 10-150 cycles

(smaller/simpler/lower-power processors are different)

add/subtract/compare are more complicated in hardware!

but much more important for typical applications

35

Page 58: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

problem: any-bit

is any bit of x set?

goal: turn 0 into 0, not zero into 1

easy C solution: !(!(x))another easy solution if you have − or + (lab exercise)

what if we don’t have ! or − or +

how do we solve is x is two bits? four bits?

((x & 1) | ((x >> 1) & 1) | ((x >> 2) & 1) | ((x >> 3) & 1))

36

Page 59: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

problem: any-bit

is any bit of x set?

goal: turn 0 into 0, not zero into 1

easy C solution: !(!(x))another easy solution if you have − or + (lab exercise)

what if we don’t have ! or − or +

how do we solve is x is two bits? four bits?

((x & 1) | ((x >> 1) & 1) | ((x >> 2) & 1) | ((x >> 3) & 1))

36

Page 60: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

problem: any-bit

is any bit of x set?

goal: turn 0 into 0, not zero into 1

easy C solution: !(!(x))another easy solution if you have − or + (lab exercise)

what if we don’t have ! or − or +

how do we solve is x is two bits? four bits?

((x & 1) | ((x >> 1) & 1) | ((x >> 2) & 1) | ((x >> 3) & 1))

36

Page 61: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

wasted work (1)

((x & 1) | ((x >> 1) & 1) | ((x >> 2) & 1) | ((x >> 3) & 1))

in general: (x & 1) | (y & 1) == (x | y) & 1

(x | (x >> 1) | (x >> 2) | (x >> 3)) & 1

37

Page 62: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

wasted work (1)

((x & 1) | ((x >> 1) & 1) | ((x >> 2) & 1) | ((x >> 3) & 1))

in general: (x & 1) | (y & 1) == (x | y) & 1

(x | (x >> 1) | (x >> 2) | (x >> 3)) & 1

37

Page 63: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

wasted work (2)

4-bit any set: (x | (x >> 1) | (x >> 2) | (x >> 3)) & 1

performing 3 bitwise ors

…each bitwise or does 4 OR operations

2/3 of bitwise ORs useless — don’t use upper bits

...

38

Page 64: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

wasted work (2)

4-bit any set: (x | (x >> 1) | (x >> 2) | (x >> 3)) & 1

performing 3 bitwise ors

…each bitwise or does 4 OR operations

2/3 of bitwise ORs useless — don’t use upper bits

...

38

Page 65: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

any-bit: divide and conquer

four-bit input x = x1x2x3x4

(x >> 1) | x = (x1|0)(x2|x1)(x3|x2)(x4|x3) = y1y2y3y4

y2 = any-of(x1x2) = x1|x2, y4 = any-of(x3x4) = x3|x4

unsigned int any_of_four(unsigned int x) {int part_bits = (x >> 1) | x;return ((part_bits >> 2) | part_bits) & 1;

}

39

Page 66: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

any-bit: divide and conquer

four-bit input x = x1x2x3x4

(x >> 1) | x = (x1|0)(x2|x1)(x3|x2)(x4|x3) = y1y2y3y4

y2 = any-of(x1x2) = x1|x2, y4 = any-of(x3x4) = x3|x4

unsigned int any_of_four(unsigned int x) {int part_bits = (x >> 1) | x;return ((part_bits >> 2) | part_bits) & 1;

}

39

Page 67: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

any-bit: divide and conquer

four-bit input x = x1x2x3x4

(x >> 1) | x = (x1|0)(x2|x1)(x3|x2)(x4|x3) = y1y2y3y4

y2 = any-of(x1x2) = x1|x2, y4 = any-of(x3x4) = x3|x4

unsigned int any_of_four(unsigned int x) {int part_bits = (x >> 1) | x;return ((part_bits >> 2) | part_bits) & 1;

}

39

Page 68: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

parallelism

bitwise operations — each bit is seperate

same idea can apply to more interesting operations

010 + 011 = 101; 001 + 010 = 011 →01000001 + 01100010 = 10100011

sometimes specific HW supporte.g. x86-64 has a “multiply four pairs of floats” instruction

40

Page 69: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

parallelism

bitwise operations — each bit is seperate

same idea can apply to more interesting operations

010 + 011 = 101; 001 + 010 = 011 →01000001 + 01100010 = 10100011

sometimes specific HW supporte.g. x86-64 has a “multiply four pairs of floats” instruction

40

Page 70: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

parallelism

bitwise operations — each bit is seperate

same idea can apply to more interesting operations

010 + 011 = 101; 001 + 010 = 011 →01000001 + 01100010 = 10100011

sometimes specific HW supporte.g. x86-64 has a “multiply four pairs of floats” instruction

40

Page 71: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

any-bit-set: 32 bits

unsigned int any(unsigned int x) {x = (x >> 1) | x;x = (x >> 2) | x;x = (x >> 4) | x;x = (x >> 8) | x;x = (x >> 16) | x;return x & 1;

}

41

Page 72: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

bitwise strategies

use paper, find subproblems, etc.

mask and shift(x & 0xF0) >> 4

factor/distribute(x & 1) | (y & 1) == (x | y) & 1

divide and conquer

common subexpression eliminationreturn ((−!!x) & y) | ((−!x) & z)becomesd = !x; return ((−!d) & y) | ((−d) & z)

42

Page 73: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

exercise

Which of these will swap last and second-to-last bit of anunsigned int x? (abcdef becomes abcdfe)/* version A */

return ((x >> 1) & 1) | (x & (~1));

/* version B */return ((x >> 1) & 1) | ((x << 1) & (~2)) | (x & (~3));

/* version C */return (x & (~3)) | ((x & 1) << 1) | ((x >> 1) & 1);

/* version D */return (((x & 1) << 1) | ((x & 3) >> 1)) ^ x;

43

Page 74: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

version A

/* version A */return ((x >> 1) & 1) | (x & (~1));// ^^^^^^^^^^^^^^// abcdef --> 0abcde -> 00000e

// ^^^^^^^^^^// abcdef --> abcde0

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^// 00000e | abcde0 = abcdee

44

Page 75: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

version B

/* version B */return ((x >> 1) & 1) | ((x << 1) & (~2)) | (x & (~3));// ^^^^^^^^^^^^^^// abcdef --> 0abcde --> 00000e

// ^^^^^^^^^^^^^^^// abcdef --> bcdef0 --> bcde00

// ^^^^^^^^^// abcdef --> abcd00

45

Page 76: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

version C

/* version C */return (x & (~3)) | ((x & 1) << 1) | ((x >> 1) & 1);// ^^^^^^^^^^// abcdef --> bcde00

// ^^^^^^^^^^^^^^// abcdef --> 00000f --> 0000f0

// ^^^^^^^^^^^^^// abcdef --> 0abcde --> 00000e

46

Page 77: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

version D

/* version D */return (((x & 1) << 1) | ((x & 3) >> 1)) ^ x;// ^^^^^^^^^^^^^^^// abcdef --> 00000f --> 0000f0

// ^^^^^^^^^^^^^^// abcdef --> 0000ef --> 00000e

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// 0000fe ^ abcdef --> abcd(f XOR e)(e XOR f)

47

Page 78: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

int lastBit = x & 1;int secondToLastBit = x & 2;int rest = x & ~3;int lastBitInPlace = lastBit << 1;int secondToLastBitInPlace = secondToLastBit >> 1;return rest | lastBitInPlace | secondToLastBitInPlace;

48

Page 79: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

49

Page 80: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

backup slides

50

Page 81: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

right shift in math1 >> 0 == 1 0000 00011 >> 1 == 0 0000 00001 >> 2 == 0 0000 0000

10 >> 0 == 10 0000 101010 >> 1 == 5 0000 010110 >> 2 == 2 0000 0010

x >> y =⌊x × 2−y⌋

51

Page 82: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

non-power of two arithmetic

unsigned times130(unsigned x) {return x * 130;

}

unsigned times130(unsigned x) {return (x << 7) + (x << 1); // x * 128 + x * 2

}

times130:movl %edi, %eaxshll $7, %eaxleal (%rax, %rdi, 2), %eaxret

52

Page 83: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

non-power of two arithmetic

unsigned times130(unsigned x) {return x * 130;

}unsigned times130(unsigned x) {

return (x << 7) + (x << 1); // x * 128 + x * 2}

times130:movl %edi, %eaxshll $7, %eaxleal (%rax, %rdi, 2), %eaxret

52

Page 84: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

non-power of two arithmetic

unsigned times130(unsigned x) {return x * 130;

}unsigned times130(unsigned x) {

return (x << 7) + (x << 1); // x * 128 + x * 2}

times130:movl %edi, %eaxshll $7, %eaxleal (%rax, %rdi, 2), %eaxret

52

Page 85: Changelogcr4bd/3330/F2017/notes/...2017/09/12  · constructinginstructions typedef unsigned char byte; byte make_simple_opcode(byte icode) {// function code is fixed as 0 for now

53