150 likes | 264 Views
Control Flow. We have: beq, bne, what about Branch-if-less-than? New instruction: if $s1 < $s2 then $t0 = 1 slt $t0, $s1, $s2 else $t0 = 0 Compiling a While Loop in C,
E N D
Control Flow • We have: beq, bne, what about Branch-if-less-than? • New instruction: if $s1 < $s2 then $t0 = 1 slt $t0, $s1, $s2 else $t0 = 0 • Compiling a While Loop in C, • Eg. Assume that i and k correspond to registers $s3 and $s5 and the base of the array save is in $s6 While (save [i]==k) i+=1; MIPS Code : Loop: sll $t1,$s3,2 add $t1,$t1,$s6 lw $t0,0($t1) bne $t0,$s5,Exit addi $s3,$s3,1 j Loop Exit:
Supporting Procedures in Computer Hardware • Procedure is a stored subroutine that performs a specific task based on the parameters with which it is provided. This is one tool that C or Java programmers use, to structure programs, both to make them understand and to allow code to be reused. • MIPS software follows the following convention in allocating its 32 registers for procedure calling: • $a0-$a3 – four argument registers in which to pass parameters • $v0-$v1 – two value registers in which to return values. • $ra -- one return address register to return to the point of origin • MIPS assembly language includes an instruction just for the procedures • jal (jump and link instruction) jumps to an address and simultaneously saves the address of the following instruction in register $ra. • jal Procedure address • Program Counter • The jal instruction saves PC + 4 in register $ra to link to the following instruction to set up the procedure return • jr $ra : The unconditional jump instruction that jumps to the address specified in a register
The calling program, or caller, puts the parameter values in $a0-$a3 and uses a jal instruction (jal X) to jump to procedure X (sometimes named the callee). The callee then performs the calculations, places the result in $v0-$v1, and returns to the caller using jr $ra. • Stack : LIFO (Last In First Out) • Push and Pop : buzzwords for transferring data to and from the stack. • SP : Stack Pointer ($sp) • Stacks “grow” from higher addresses to lower addresses. This convention means that we push values onto the stack by subtracting from SP. Adding to SP on the other hand, shrinks the stack, thereby popping values from the stack.
The parameter variables g, h, i, j correspond to the argument registers $a0,$a1,$a2,$a3 and f corresponds to $s0. int leaf_example ( int g, int h, int i, int j) { int f; f = (g+h) – (i+j); return f; } Compiled MIPS code leaf_example: addi $sp, $sp,-12 # adjust stack to make room for three items sw $t1,8($sp) sw $t0,4($sp) sw $s0,0($sp) add $t0, $a0, $ a1 # statements corresponding to the body of the procedure add $t1, $a2, $ a3 sub $s0, $t0, $t1 add $v0, $s0,$zero
Before returning, we restore the three old values of the registers we saved by popping them from the stack lw $s0, 0($sp) # restore values from stack back to register lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 jr $ra # jump back to calling routine • $t0-$t9 : 10 temporary registers that are not preserved on a procedure call.
Policy of Use Conventions Register 1 ($at) reserved for assembler, 26-27($k0,$k1) for operating system
filled with zeros 0000000000111101 0000000000000000 0000000000111101 0000100100000000 How about larger constants? • We'd like to be able to load a 32 bit constant into a register • Eg. 0000 0000 0011 1101 0000 1001 0000 0000 • Must use two instructions, new "load upper immediate" instruction lui $t0, 61 • Then must get the lower order bits right, i.e., ori $t0, $t0, 2304 0000000000111101 0000000000000000 0000000000000000 0000100100000000 ori
Addresses in Branches and Jumps • Instructions: bne $t4,$t5,Label Next instr is at Label if $t4 ≠ $t5 beq $t4,$t5,Label Next instr is at Label if $t4 = $t5 j Label Next instruction is at Label • Formats: • If the addresses of the program had to fit in this 16 bit field, it would mean that no program can be bigger than 216, which is far too small to be a realistic option today. • Alternative is to specify a register that would always be added to the branch address, so that a branch instruction would calculate the following: • PC = PC + Branch address • This form of branch addressing is called PC relative addressing. The MIPS address is actually relative to the address of the following instruction (PC + 4), as opposed to the current instruction (PC). op rs rt 16 bit address I J op 26 bit address
Addresses in Branches • Instructions: bne $t4,$t5,LabelNext instruction is at Label if $t4≠$t5 beq $t4,$t5,LabelNext instruction is at Label if $t4=$t5 • Formats: • Could specify a register (like lw and sw) and add it to address • use Instruction Address Register (PC = program counter) • most branches are local (principle of locality) op rs rt 16 bit address I
While (save [i]==k) i+=1; MIPS Code : Loop: sll $t1,$s3,2 add $t1,$t1,$s6 lw $t0,0($t1) bne $t0,$s5,Exit addi $s3,$s3,1 j Loop Exit: If we assume we place the loop starting at location 80000 in memory, what is the MIPS machine code for this loop?
Overview of MIPS • simple instructions all 32 bits wide • very structured, no unnecessary baggage • only three instruction formats op rs rt rd shamt funct R I J op rs rt 16 bit address op 26 bit address
Summary • Instruction complexity is only one variable • lower instruction count vs. higher CPI / lower clock rate • Design Principles: • simplicity favors regularity • smaller is faster • good design demands good compromises • make the common case fast • Instruction set architecture • a very important abstraction indeed!
Program 2.8 (unsolved problem in Book) • srl $s0,$s1,2 • andi $s0,$s0,0X00ff • andi $s1,$s1,0Xfffe • ori $s1,$s1,0X0002 OR • sll $s0,$s1,22 • srl $s0,$s0,24 • andi $s1,$s1,0Xfffe • ori $s1,$s1,0X0002