200 likes | 218 Views
Understand the power of conditional moves in machine-level programming, unlocking efficient control structures like if-then-else statements, loops, and switch statements. Learn how conditional moves optimize code without disrupting instruction flow.
E N D
Carnegie Mellon Ithaca College Machine-Level Programming IV ControlComp 21000: Introduction to Computer Organization & SystemsSystems book chapter 3*
Ithaca College Today • Control: Condition codes • Conditional branches • If-then-else statements • Conditional moves • Loops • Switch Statements
Ithaca College Using Conditional Moves • Conditional Move Instructions • Instruction supports: if (Test) Dest Src • Supported in post-1995 x86 processors • GCC tries to use them • But, only when known to be safe • Why? • Branches are very disruptive to instruction flow through pipelines • Conditional moves do not require control transfer C Code val = Test ? Then_Expr : Else_Expr; Goto Version result = Then_Expr; eval = Else_Expr; nt = !Test; if (nt) result = eval; return result;
Ithaca College Conditional Move * source/destination may be 16, 32, or 64 bits (not 8). No size suffix: assembler infers the operand length based on destination register • cmovX Instructions • Jump to different part of code depending on condition codes
Ithaca College Conditional Move Example long absdiff (long x, long y) { long result; if (x > y) result = x-y; else result = y-x; return result; } absdiff: movq %rdi, %rax # x subq %rsi, %rax # result = x-y movq %rsi, %rdx # y subq %rdi, %rdx # eval = y-x cmpq %rsi, %rdi # x:y cmovle %rdx, %rax # if <=, result = eval ret
Ithaca College Bad Cases for Conditional Move Expensive Computations • Both values get computed • Only makes sense when computations are very simple val = Test(x) ? Hard1(x) : Hard2(x); In general, gcc only uses conditional moves when the two expressions can be computed very easily, e.g., single instructions. Risky Computations val = p ? *p : 0; • Both values get computed • May have undesirable effects (always dereference p but it may be null!) Computations with side effects val = x > 0 ? x*=7 : x+=3; • Both values get computed • Must be side-effect free
Ithaca College Practice Problem • Generation test: leaq 0(,%rdi,8), %rax testq %rsi, %rsi jle .L4 movq %rsi, %rax subq %rdi, %rax movq %rdi, %rdx andq %rsi, %rdx cmpq %rsi, %rdi cmovge %rdx, %rax ret .L4: addq %rsi, %rdi cmpq %-2, %rsi cmovle %rdi, %rax ret long test (long x, long y) { long val = _________; if (_________){ if (__________){ val = ________; else val = ________; } else if (________) val = ________; return val; } test %rsi, %rsi Does %rsi & %rsi
Ithaca College Practice Problem • Generation test: leaq 0(,%rdi,8), %rax testq %rsi, %rsi jle .L4 movq %rsi, %rax subq %rdi, %rax movq %rdi, %rdx andq %rsi, %rdx cmpq %rsi, %rdi cmovge %rdx, %rax ret .L4: # x <= y addq %rsi, %rdi cmpq %-2, %rsi cmovle %rdi, %rax ret long test (long x, long y) { long val = 8*x; if (y > 0){ if (x < y){ val = y - x; else val = x & y; } else if (y <= -2) val = x + y; return val; }
Ithaca College Condition Codes (Explicit Setting: Test) • Explicit Setting by Test instruction • testqSrc2, Src1 • testqb,a like computing a&b without setting destination • Sets condition codes based on value of Src1 & Src2 • Useful to have one of the operands be a mask • CF set to 0 • ZF set when a&b == 0 • SF set when a&b < 0 • OF set to 0 Note: typically the same operand is repeated to test whether it is negative, zero, or positive: testl %rax, %rax sets the condition codes depending on the value in %rax Note 2: there are also testl, testw and testb instructions.
Ithaca College Reading Condition Codes • SetX Instructions • Set low-order byte of destination to 0 or 1 based on combinations of condition codes • Does not alter remaining 7 bytes
x86-64 Integer Registers %rax %r8 %al %r8b • Can reference low-order byte %rbx %r9 %bl %r9b %rcx %r10 %cl %r10b %rdx %r11 %dl %r11b %rsi %r12 %sil %r12b %rdi %r13 %dil %r13b %rsp %r14 %spl %r14b %rbp %r15 %bpl %r15b
Reading condition codes • Consider: setlD (SF^OF) Less (Signed <) D (SF^OF) • First compare two numbers, a and b where both are in 2’s complement form using an arithmetic, logical, test or cmp instruction • Then use setX to set a register with the result of the test cmpq %rax, %rdx setl %al puts the result in byte register %al
Reading condition codes (cont) • Assume a is in %rax and b in %rdx cmpq %rax, %rdx setl %al puts the result in byte register %al • First instruction sets the condition code. • cmpq computes b – a • If b < a then b – a < 0 If there is no overflow, this is indicated by SF • If there is positive overflow (b – a is large), we have b – a < 0 but OF is set • If there is negative overflow (b – a is very small), we have b – a > 0 but OF is set • In either case the sign flag will indicate the opposite of the sign of the true difference. Hence, use exclusive-or of the OF and SF • Second instruction sets the %al register to 00000000 or 00000001 depending on the value of (SF^OF) setl D ; D (SF^OF)
Reading condition codes (cont) • Example: assume %rax holds 20 and %rdx holds 50 cmpq %rax, %rdx 50 – 20, SF 0, OF 0 setl %al %al 0 ^ 0 = 00000000 • Example: assume %rax holds 0x8000001 and %rdx holds 20 cmpq %rax, %rdx 20 – (-2147483647) , SF 1, OF 1 setl %al %al 1 ^ 1 = 00000000 setq gives false; 20 is not less than -2147483647 setl D ; D (SF^OF)
Reading condition codes (cont) • Example: assume %rax holds 20 and %rdx holds 0x8000001 cmpq %rax, %rdx (-2147483647) - 20 , SF 0, OF 1 0x80000001 + 0xFFFFFFEC = 0x7FFFFFED (note that 7 = 0111) setl %al %al 0 ^ 1 = 00000001 setq gives true; -2147483647 is less than 20
SetgGreater (Signed) ~(SF^OF)&~ZF ~SF&~OF If this is zero, can’t be > First do an arith, logical, cmp or test. Then use the flags If the overflow flag is set, can’t be > if we did a cmpl or testlas the previous instruction. Why? CF ZF SF OF Condition codes
Ithaca College Reading Condition Codes (Cont.) • SetX Instructions: • Set single byte based on combination of condition codes • One of addressable byte registers • Does not alter remaining bytes • Typically use movzbl to finish job • 32-bit instructions also set upper 32 bits to 0 intgt (long x, long y) { return x > y; } cmpq %rsi, %rdi # Comparex:y setg %al # Set when > movzbl %al, %rax # Zero rest of %rax ret
Ithaca College Reading Condition Codes (Cont.) %rax %ah %al %rdx %dh %dl All 0’s: 0000000000000000000000000 %rcx %ch %cl %rbx %bh %bl Either 00000000 or 00000001 %rsi %rdi intgt (long x, long y) { return x > y; } %rsp %rbp cmpq %rsi, %rdi # Comparex:y setg %al # Set when > movzbl %al, %rax # Zero rest of %rax ret
C Control if-then-else do-while while, for switch Assembler Control Conditional jump Conditional move Indirect jump (via jump tables) Compiler generates code sequence to implement more complex control Standard Techniques Loops converted to do-while or jump-to-middle form Large switch statements use jump tables Sparse switch statements may use decision trees (if-elseif-elseif-else) Ithaca College Summarizing
Ithaca College Summary • Today • Control: Condition codes • Conditional branches & conditional moves • Next Time • Loops • Switch statements • Stack • Call / return • Procedure call discipline