 So, we are discussing 32 bit bits ISN, hopefully we will finish up today. Just to quickly remind you, we looked at these ALU instructions. We talked about the limit on 20 point instructions. We also looked at the memory operations. There are only two types, loads and stores. And also we talked about how to synthesize direct addresses in a movie. And we talked about the special instructions, load word left and load word right. Similarly, you have store word left and store word right, store word right. So, we started talking about control transfer instructions. We looked at jump instructions. And there are two types of them. One is unconditional jump and procedure calls, where the target is computed like this. The target, this comes from your instruction. These are 26 bits. And your upper four bits come from the next piece. And for indirect jumps, when the target is not drawn, you usually use JR, that is jump register or jump and link register or JALAR instruction. And both take a register operand where the target is found. So, procedure return is written, we use JR with dollar 31 as your argument. So, dollar 31 is actually result for storing the written address. So, any questions so far? So, there is a sheet of attendance circulating somewhere. So, please sign if you are registered in the course. So, what else do we have in control transfer? Of course, we have conditional branches. So, here as we discussed earlier that there are two parts. One is your condition, that is usually it is a comparison. And you have the target, if the condition transfer to be true, which way it will go? So, all conditional branches are compare and jump time. So, in MIPS, you usually fuse these two links, that is single instruction. It is not like you compare in one instruction and then you jump in the next instruction. It is not like that, it is actually compare and jump, fuse to that. And you always use PC relative immediate offsets. And these offsets are always signed in statement. And the reason is obvious because you may want to go forward or backward. So, you should be able to do both. Unless you do a sign extension, you cannot sign negative offsets. So, here are the examples. This is not the exhaustion list of conditional branches. If you want, you should look up your dot c pi that I posted. Nonetheless, so DEQ stands for branch if equal. So, here what it means is that if dollar one is equal to dollar two, then your target is this, PC plus four plus 100 shifted by two. So, notice that here we are mentioning the offset ignoring the last two bits because we mentioned that last two bits are always zero. So, there is no need to at least specify this. And we do not add it to PC, but to PC plus four, because of the same reason we used PC plus eight in there. So, does anybody remember this one? That my return address was PC plus eight, when you took a procedure, instead of PC plus four. So, we actually skip over one. So, we talk about this today. In fact, in this slide I think there is one. So, just remember that your offset is already equal to PC plus four, not PC. P and E is similarly the opposite of that. Branch if not equal. BG is at branch if greater than equal to zero. So, dollar one if it is greater than equal to zero, then you should go to this particular target. Branch less than equal to zero, branch less than zero, branch greater than zero. So, notice that only these two cases you will be comparing two registers. In all other cases one register gets compared against zero. However, if you want, you could actually synthesize these using two instructions. For example, if you want to let us say, for example suppose if you did not have these instructions, that no, not this one, let us suppose this one. BNTZ, branch less than zero. What you could do is you first would compare, you first would execute a set less than immediate instruction. Where your instruction would be SLTI, dollar one, let us make it a different register, dollar one, dollar zero. Essentially what we will do is it will set dollar two depending on whether dollar one is less than zero or not. Then you could actually use BQ or BNE to figure out whether the comparison possible. However, that is not needed. So, we have actually fused these two. So, they gave compiler more freedom in choosing instructions. All branch and jump instructions have a delay slot. So, right now I only have to explain why this is so. But what this means is that the instruction right after a branch or jump instruction is always executed. So, you have a branch instruction, you compute your target. Suppose the condition is that you should go to that target. But before going there, you will execute the next instruction. So, it is as if the effect of the branch is delayed by one slot. That is why the name comes, the delay slot. Is this concept clear to you? So, we will find out why this was required actually. This is one example where how your pipeline structure influences what the compiler sees. Because here now, compiler also will have to know this, that oh, the instruction after the branch will always be executed. So, the compiler's job would be to fill up that particular instruction with something useful. So, instruction right after the jump for branch is always executed. Now, that explains why you should add it to PC plus 4. Because it is as if the branch instruction was actually at PC plus 4, not at PC. Similarly, the procedure return address should be PC plus 8. Because the procedure is a PC procedure call. The PC plus 4 is always executed. You should come back to PC plus 8 when the procedure completes. Any question? Sir, for other instructions, when the PC gets updated? Sorry, second. For other instructions about two branches, when the PC gets updated? When we are not at this point even thinking about when. We will not answer that question. Because we do not have any emotion or time at this point. We are just looking at functional outcome of the program. We are just trying to explain what an instruction should be. How long it takes? When what happens? I am asking this difference. Just you fetch the instruction and you have the next PC. Right. So, you can think of it like that. If you fetch the instruction, execute the instruction 0 time, you update the PC, fetch the next one and so on. Everything happens in 0 time. We will bring in time when we try to implement the instruction set. That is why the time will come into picture. Any other question? So, here is an example. Let us try to walk through it. So, here we are doing a search. Essentially building a histogram. So, count is initialized to 0. And I run over a sub array. It starts at a head, index head. And we run over till we reach n, looking for a particular key. And you count how many times a key updates. These are very basic part of building a histogram. So, just for the sake of example, I want to show you the assembly program. You follow what really happens. So, let us assume the following allocation that the compiler has done. Suppose, count is in register 5. The loop index i is in register 6. Head is in register 1. The start address of A is in dollar 2. Key is in dollar 3. N is in dollar 4. And A is in visual array, which means each element is 4 marks. So, compiler has already allocated these things. And it has set up this particular scenario. Now, let us see how the loop executes. First, what is this doing? The first line, dollar 5 is count. Initializing to 0. So, dollar 0 is hardware to 0. So, it is just adding 0 to 0 to get 0. So, that is initializing dollar 5. What is this doing? Dollar 1 is head. And dollar 6 is i. What is it doing? So, it is doing this i equal to head. Then moving head to i. Then we start the loop. We first check, first compare dollar 4 and dollar 6. And if dollar 4 is less than dollar 6, we set dollar 9 to 1. So, let us see what is this. Dollar 4 is N. And dollar 6 is i. So, what is it doing? It is doing this. i less than equal to N. And if that is so, then it checks if dollar 9 is not equal to dollar 0. Then it exits. So, when it could be not equal, it could be 1 in that case. It is dollar 9. If dollar 9 is 1, that means we have already reached the loop bound. We should exit. And jump to exit and do something. So, after the loop, whatever. Sir, it should be less than equal to N. Less than, there is no less than equal to. So, you are saying this is not going to work, is it? i less than equal to N. Dollar 4 is N. No, it is just inverting this comparison, right? So, that is ok. Sir, it is not equal to less than equal to N. It is just inverting this particular comparison. i less than equal to N, inversion of that is what? N less than i, right? That is exactly what this is doing. It is taking the other way. So, that is why you get this BME. Is it very easy? Alright. So, next, what do we do? So, remember that this instruction is a delay slot of this BME. So, it will always be executed. In this case, it does not really matter. Because this branch will be taken exactly once. It is a kind of like when the loop is done. At the end, this branch will be taken. In other words, in all other cases, it will actually just penalty. So, dollar 6 gets shifted left by 2 positions. So, what is dollar 6? 6 i shifts left by 2, puts it in dollar 7. So, that is if you are saying dollar 6 multiply by 4, right? So, we will try to understand what it is doing. Let us see how it uses dollar 7. Then we will understand. It adds dollar 7 to dollar 2 and puts it in dollar 7. Dollar 2 is what? Base of A. So, what is dollar 7 now? Can anybody guess? It is address of A i, right? Adress of A i. So, then it does a load. Loads from dollar 7 to dollar 8. So, now we have dollar 8 contains A i. Then it checks if dollar 8 is not equal to dollar 3. What is dollar 3? Dollar 3 is key. If it is not equal, then it goes to next, where it just takes me back there. So, essentially this is the nth spot. There is no nth spot. So, it just goes back to the next time question. Remember that this instruction is in the delay slot. It will be executed. And here it actually increments i. So, i plus plus is putting the delay slot. That is a very useful way of using the delay slot. Otherwise, you will be actually wasting another instruction. So, you go back here. Otherwise, you continue and you increment count here by 1. Because if you are here, that means you actually got the key, right? And then anyway you come here, you go back. What is j? Jump loop. That is an unconditional jump which takes you here. No, that is the mnemonic used by loops j. So, j means it is an unconditional jump. Any question on this? No, that means no operation. So, can you even guess why is it here? It does nothing. Because that is the other execution of the operation. Exactly, right. So, this is the delay slot of jump, right? And compiler could not find anything to fill in this slot. So, it just puts a knob instruction. So, in essence when it executes, it will actually waste one instruction. So, this is why the compiler becomes important. The compiler should be able to find something useful to put in the delay slot. Otherwise, you will end up wasting this delay slot. So, in this case the compiler could find anything. So, it has to put a knob. When you cannot execute an arbitrary instruction here, it will let me change the correct execution. Any other question? Clear? Okay, proceed your call. So, every instruction set comes with a calling convention. That is what really happens on a call. So, specifically it tells you how the parameter should be passed, number one. And how the stack should be prepared for the procedure. So, in this case in MIPS, parameters are passed in registers. So, if you have four parameters, you can pass all of them to registers. Whereas MIPS results four argument registers. But of course, you can have procedures that require more than four parameters. If you have more parameters, they are split on the stack. You pass that to the stack. Compiler tries best to allocate local scalar variables in registers. Stack is used for spilling. So, in a procedure if you have local scalar variables, that is non-arrays, the compiler will try to put them in the registers. So, if you have a lot of registers, in this case, there will be a lot of registers. There are two dedicated general purpose registers. That point to top of the stack called the stack pointer. And start of the procedure frame called the frame pointer. So, procedure frame is essentially a sub-portion of the stack. So, the frame pointer points to the starter cluster. So, we will see one example. And there is something called a global pointer where global static scalar variables are allocated. So, there is a 64 kilobyte static area at compile time. And the global pointer points to the start of that region. And it is always accessed with dollar GP plus some offset. These are determined at link time. Because the linker actually establishes exactly where the global segment will reside in the network. So, these offsets get determined only at the link time. It is a memory that clearly you have stack pointer register, frame pointer register, global pointer register. You have four argument registers. And local variables go to registers. Otherwise, there is build, extra argument and speed on the stack. So, pictorially, this is what it looks like. You have the address grows in this direction. You can see that, right? So, this is zero. This is the highest address. This portion is reserved for kernel in the operating system, right? This is usually called the text region where your code lies. So, this is where your program will be loaded. Then comes the static data. So, static data means the global data and whatever local variables you have. Sorry. This is just the global data. That is the global pointer data. They have dynamic data. This heap, which grows out. And you have the stack, which grows down. And you can imagine what will happen with the stack and the heap code. Then there will be a catastrophic action. So, which is why that is exactly what happens when they are about to collide. The operating system will raise the alarm. The alarm of memory normally is here. Is it clear to everybody? So, usually, so you can calculate actually. If you calculate that particular number, it will come to about two gigabytes. So, these are region, although I say that it is going to kernel. So, what it really contains is basically the interrupt handlers. So, often this is also called the whole thing is the user space. But you cannot really access this region. You have to go to the operating system to access this region. So, here your kernel real doesn't reside. What resides is basically the interrupt handlers. So, upper 2 GB is the kernel space. That is why you are actually kernel code resides. Kernel code 100 data and all this is the operating system data. So, that is the upper 2 GB. The lower 2 GB is the user space. I have just shown that. On processor reset, execution starts at that particular address. That is where it resides. When I push that button, the program counter goes. The program counter gets loaded with that particular constant. And that is where it will start. And stat grows downward while hip grows upward. So, if you actually take this constant and try to find out why it actually resides, it finally resides in this upper 2 GB area. So, it is really the kernel space. That is where it will actually start from. The processor gets reset in the kernel space. Kernel takes up your control and finally, hands it over to whatever program you want to run. Yes. What do you actually mean by processor reset, sir? So, you have this. So, when you boot the machine, where should my control ports go? When will you start the system? Yes, exactly. So, when you boot the machine, the program counter has to get something. That is why the first instruction gets executed. And that is that address. This is the first instruction. And usually, you will have the bootstrap loaded there. So, this is the place for MIPS. It is not, of course, not for any processor. So, what is the register convention? So, we talked about this 4 argument registers. So, here is the full register convention for MIPS. So, there is no convention specified for floating point registers. So, only convention are specified for integer registers. So, dollar 0 is hardware to 0. It is actually not implemented as a register. Whenever you ask for dollar 0, the hardware will actually provide it with all 0 constant. Dollar 1 or dollar at is reserved for assembler. So, often you will find that, well, in this course, although we will not be looking at MIPS, if you ever get to use a MIPS compiler, and if you try to disassemble the compiler code, it has subtle mnemonics called LA, which is actually not a MIPS instruction. So, it is often used to load constant absolute addresses. That is what it stands for, load address. So, assembler's job is to convert those two to whatever sequence of instructions that we synthesized last time. Dollar 2, dollar 3, or sometimes called dollar v 0 and dollar v 1 are return values of function with upper 32 bits in dollar v 1 and lower 32 bits in dollar v 0. So, we can return a 64 bit value. Dollar v 1 also holds a system call number before executing a system call. So, dollar v 1 has a dual cost. So, in one case, dollar v 0, dollar v 1 together will specify your return value. If it is a 64 bit value, if it is a 32 bit value, then only dollar v 0 is enough. And dollar v 1 is used to hold the system call number before tapping to the operating system. Dollar 4 to dollar 7, or sometimes written as dollar a 0 to dollar a 3 are procedure arguments saved by the caller. That is very obvious. They have to be saved by the caller because caller is actually going to set the arguments. So, before setting the argument, you can save the argument registers and set them. Dollar 8 to dollar 15 are called t 0 to t 7 are temporaries saved by the caller. So, these are the callee or the procedure is free to use these registers. That is what it means. It is saved by the caller. Dollar 6 to dollar 23 or dollar s 0 to s 7 are callee saved registers. So, what that means is that caller can actually keep the values in these registers unchanged and then forget about them without even worrying about them because it knows that if the callee wants to use these registers, it will be saved and it will be reserved before return. Yes, yes, yes, they actually happen on stack. It is same on the stack and pop from the stack. 24, 25 or t 8 and t 9 are two more temporaries used for the same purpose. 26, 27 or k 0, k 1 are reserved for kernel. If the kernel ever requires any registers for any purpose, it can use those. 28 is a global pointer, 29 is a stack pointer, 30 is a frame pointer and 31 is a return address. That is a complete register map of course. Clear? Any question? So, this is very useful because for example, if the operating system gets a system call, it knows where to look for to get the system call number that is dollar view. So, that is the purpose of mentioning a convention. So, little bit of register saving. Caller saves the registers that are not preserved across calls. Of course, needed only if caller wants some value to be preserved. So, before calling the procedure, save the registers and these are the ones that are caller saved we just mentioned. Callee saves the registers that are required to be preserved across calls. Needed only if callee uses these registers. So, these are the callee saved registers. So, these are of extreme importance. If you do not save these, you are going to mess up the execution. So, the global pointer may be restored on a procedure call. Stack pointer may be restored on a procedure return. Frame pointer same with return address. Because if you have nested calls, return address should must be come up appropriately. The MIPS GCC cross compiler, native CC compiler do not use frame pointer. So, in that case dollar 30 is treated as callee save basic. So, frame pointer is usually not used. I am showing you a code without the frame pointer. Question? So, let us see what happens on procedure call. Yes. So, if we have greater number of arguments in that. Yes. So, 4 arguments can be passed in 4 registers. The remaining ones will go on the stack. And then we pop from the stack pointer. So, what does the caller do? It saves the caller save registers it needed. It loads the arguments. First 4 in dollar 80 to dollar 83 raised on stack. And then call JAL or JALA. So, JAL is a direct procedure call. JALA is an indirect procedure call. JALA will have register argument where your target will be there. What does the callee do? So, in this description we use the frame pointer. Because that is easier to explain. It will first save the frame pointer at the top of stack. That is 0 dollar speed. Allocate stack for frame. So, it will essentially what we do is that remember that stack grows down. So, it will bring the stack pointer down by frame size. Now, essentially what we will do is what we will do is we will use. So, stack pointer was here. We will bring it down here. So, we will use this area for the procedure. It has a procedure frame. So, compiler knows the frame size for this procedure. So, it can actually calculate what it is going to do. So, with the callee save registers it needed before we start doing anything. Adjust the frame pointer to point to the beginning of the frame. So, what is the beginning of the frame? This stack pointer we add the frame pointer subtract 4. Why subtract 4? Why subtract 4? Because stack pointer is pointing from that. So, our stack pointer was here. This is my frame. So, I bring the stack pointer down here. And then I want the frame pointer to point to here. So, that I can use the. So, what I am doing is I am leaving out the top 4 bytes. Why is that? Is it? Internet address is already. Internet address, what am I? Why am I leaving out the top 4 bytes? Or maybe it is there. Just read it carefully. What is there? At that location. Frame pointer, exactly. I just saved the frame pointer there at zero dollar ST. I cannot overwrite that. So, that is why I have to leave out the 4 bytes at the top. Is it clear to everybody? What happens on return? By the way, somebody was mentioning about return address. Keep in mind that return address is not on the stack. It is in the register in MIPS. That is dollar 31. That is dedicated to store the return address. So, when you do a jump and link, part of this instruction is to put the return address in dollar 31. What happens on return? Call it places the return value dollar V0 and dollar V1. It is a 64 bit value. There is more than one function called also because we call that. Yes. How do we do that in MIPS? We are not storing in a stack. We are not storing in a stack. Yeah. How do we end up with that? Right, exactly. That is a very good question. So, the answer is here. Call is saved registers have dollar RA. So, if the call makes one more function call. That means it is going to modify dollar RA. You will have to save dollar RA. So, you put it on the stack and then put the new return address in RA. So, yes, you are right. If you have nested calls, the return address will actually value stack up in your stack down in your stack. So, what happens on return? Call it places the return value dollar V0 and dollar V1. It is a 64 bit value. Restore any call is saved registers from stack. Pop stack frame. So, SP plus SP becomes SP plus frame size. So, you are not bring it up here. And then execute JR dollar RA. Dollar RA contains your return address. So, this instruction will modify your program counter to be equal to the content of dollar RA. Any question? Proceed your call. So, this is what it looks like. I just show it to you here. So, these are your arguments coming from the caller. So, this is after doing all these adjustments. Stack pointer was pointing here, was brought down here after subtracting the frame size. So, frame size a frame contains call is saved registers and speed local variables. The compiler will have the responsibility of calculating this exactly, how much is needed. Usually the compiler actually overestimates this. You will find in examples that we showed. And then it will bring up the frame pointer here and then start there. And when the procedure returns, the stack pointer will be brought up again here. So, that the caller sees exactly the way the stack pointer was when the procedure was called. So, here is an example, factorial with the recursion. So, this is the C code. Any question on the C part? So, if n less than equal to 1, that is when we start unfolding the recursion. Otherwise, we return n times factorial. So, here is the code. So, let us try to understand what is happening. So, this one does not have any frame pointer. So, this is taking directly. So, I essentially fade this C code to a mixed compiler. And this is what it generates. So, you do not have any frame pointer. Because mixed compiler does not use frame pointer. So, the first one adjusts your stack pointer. So, it calculates that I will require 40 bytes for this particular procedure. Then what do I do? I store dollar is 0 into 24 SP. So, we will see what it contains. Currently, the whole intention of doing this is that s 0 is a callisab register. And the function wants to use s 0 for some purpose. That is why it is saving this register on the stack. Then it moves a 0 to s 0. This particular instruction does that only. It adds 0 to a 0. A 0 is the, what is a 0? What is a 0? Laura, argument, what is it in this case? N. N. So, dollar is 0 should contain n. So, I am just moving n to dollar is 0. Then I compare s 0 to 2. Set less than immediate. If dollar s 0 is less than 2, which is exactly same as doing this, n less than 2. So, I store the value in dollar v 0. Dollar v 0 is the return value. If n less than equal to, if n is less than 2, then the return value is 1. That is exactly what you are doing. Then if not, I am here. Well, I have not yet compared. I have not yet checked anything. So, now I come here. I put the return address on $32. Save it on the stack. And then I check what happened to v 0. If it is not equal to 0, that means this comparison was actually favorable and I jumped to level 1. So, what do I do in level 1? Well, actually this was not really needed. It just moves 1 to dollar v 0. And then pops r a from stack. Pops s 0 from stack returns. And here it adjusts the stack quantity in the delay slot of the return. All right. Is this path okay to everybody? From here to here to here to here. Sir, are you supposed to have it to s 0 to y? Why do I put it? Yes, exactly. So, actually in this path this is not needed. But it was just preparing for this particular call. That is all. You are right. Is this clear to everybody? The genesis of this, synthesis of this particular statement. This is this one. All right. Also notice that this is going to be in the delay slot. So, it also saves global point on the stack. So, again preparing for the recursive call actually. So, notice that the compiler actually prepares itself for the common case. That is in most cases there will be a recursive call. Gases that actually. Then it does decrements s 0. Prepares this argument in minus 1. All right. And then calls factorial. Jump and link factorial. Nothing to put in the delay slot. It puts a no off. The return will be here. The return will come back here. Do the multiplication s 0 with v 0. v 0 is the return value of factorial. Multiplies that with s 0. S 0 contains n at this point. So, it computes this one. Moves the value from low to v 0. So, since I have a return time of e t here. It knows that it is a 32-bit value. It does not even care about what is in height of multiplication. And then jumps to level 2. This is essentially preparing to return. So, that is the question. All right. So, my last slide. We are done. So, in summary we have three formats of bits instructions. All the instructions are 32 bits in size. Off-code is always six bits. The upper six bits are off-code. And this is six bits. So, how many instructions do I have? So, what are the three formats? The first format is called the registered format or ALU format. So, let us suppose this is my ALU format. So, this bit will be all here. It dedicates the lower six bits to specify a function. So, you can have 64 different ALU functions. And then you have to specify your source and target registers. So, you have r s, r t, r d and s a. So, you have the s a is the shift amount. So, remember that you have this shift left, logical, shift right, logical, shift right instruction where you mention an constant shift amount. And of course, since my registers are 32 bits. It is a 32-bit ISA. Shift amount cannot be more than 32. That is why it is 5 bits, the shift amount. And then I have the destination register. That is r d, which is also 5 bits. And then I have two sources, r s and r t. That is the ALU format encoder. So, what is the trigger for the decoder? Decoder looks at the off-code. Since all zeros knows that it is an ALU instruction, looks a funk, knows what to do, extract the sources. If the shift instruction will extract the shift amount, do the computation, put the result in register r d. So, these are all 5 bits because MIPS has 32 integer registers. So, this is only the integer instruction format, by the way. I am not even showing the coding format in the instruction format. You can look it up in C5, it is there. Any question on the ALU format? So, this is called the register instruction format because it operates only on registers. So, it is an immediate format. So, this one takes an immediate constant as part of the instruction. So, this can be arithmetic instructions like your add immediate or your or immediate. It can be branch instructions where you use the immediate field for specifying the branch offset. It can be load stored where you specify the displacement in the immediate field. So, anything that uses an immediate value. Different off-code for each instruction. So, it is not like this. So, the format is that you have to off-code here which is 6 bits. Then you have r s and r t in exactly same positions. 5 bits each. So, how many bits are left? 16 bits. This is the immediate. So, decoder looks up the off-code and knows what this instruction is. Like it could be an add instruction, it could be a branch instruction, and treats the immediate accordingly. Either 0 extents or sign extents and whatever way it needs to be written. R s is the first source or base and r t is the second source or result. So, what does this mean? So, in the cases where, so in most cases this immediate will be one operand. And will require one more source operand and that will come from R s. So, it is the first source. Or if it is a load instruction, R s is the base address. If it is a store instruction, R s also is the base address. R t is the second source. Can you think of an instruction where R t would be the second source? An instruction that uses an immediate value. So, I just mentioned that the immediate value should always, should already be an operand for this instruction. And R s is the first source. Why should it be one more source? So, in most common case, R t would be the result. Like for example, if you have an add I instruction, you add the immediate with the content of R s put the result in R t. In what cases you have a second source? So, of course, that will tell you that in such instruction there cannot be any result as such. Because there is no place to store it actually. Everything is exhausted. R s is the source, R t is the source. I do not have any other instruction to store. What is such an instruction? What instructions do not have a registered value to be included? A registered result as such. Sorry. They do not have a result. They have only 2 and 4. That is a result, right? You do an OR operation. I do not understand why you said 2 and 4. It is an OR operation. So, which one you are writing? Multiplication. Do not make some multiplication with this. Multiplication is a different thing. Multiplication does not have an immediate. Some instruction that uses an immediate value, but does not have a result that goes to registers. Sorry. Jump format is the last one. We have not yet got there, but you are close. Yes. Procedural costs are also in the last format. Conditional branches, exactly. Thank you very much. Conditional branches, like for example, if you take B, E, Q, it will be comparing values in R s and R t and using the immediate for the branch target offset. So, this is an instruction where the outcome is not written back to any register. Outcome is used to update the PC media. Anything else? Is everybody clear about that? B, E, Q and D, A, G. These are the two branch instructions where you consume both the sources. There is no problem. Any other instruction that would have an outcome written back to register? What about store operations? What do they do? What do they do? So, I tell you that the store operation falls into this category. How will you tell me the address? The answer is already there in the slide. You just need to read. How will the store instruction be? R s is the base. R s is the base, alright. R t is the base. That is what you think? R t will be the offset? R t. How many of you think R t will be the value immediate for the result? R t is which value? Which value? Very good. Thank you. So, your address will be R s plus sign extended immediate. And R t is the value that will be stored. By the way, we are not really storing R t. Although, I am repeatedly saying that I am storing R t. I am storing the value in register R t. Like R t will have a value like 20. So, I will go to register 20 and store that value. Okay. Remember, alright. Third format is called the jump format. So, this is immediate format. So, this is used for direct jumps like J and JAL. Essentially, these are the only two instructions that fall in this category. Here you have an opcode, 6 bits and a 26-bit target. So, you can jump across 64 million instructions. That is it. So, that is your MIPS. So, now you can calculate how many instructions the integer side has, right. This is 65 plus 64. So, you have 129 instructions. Actually, all of these are not used. So, just I just want to re-emphasize the fact that MIPS is the risk ISA. So, the philosophy was to be minimal. You have this set of instructions. As long as you can do pretty much everything more or less efficiently, you are fine. So, it is not like you should provide one very complicated instruction which is going to be used in 1 million instructions. That is not really good. You support the most common instructions, common news instructions. The remaining ones you should be able to synthesize. So, you are saying that if you have a constant that is more than 16 bits. Well, that is what we discussed last time, right. How to synthesize larger constants. Yes. That is the only way. So, should we start now or what do you think? Yes, only 5 minutes left. Maybe next time we will start. So, there is a sheet of attendance start writing out the sign before we leave. And so, next time, Sudhanshu is going to talk about binary instrumentation too that will be used for in our homeworks. You understand x86 instructions in architecture. So, that is what we will do in the next class. Okay, thank you.