 Introduced the basics of the MIPS ISA and we talked about the data types, I just remind you there are four data types byte, half word, one, and double word. And so the double word instructions are relevant only in a 64-bit ISA, and 32-bit ISA will only have up to 32-bit instructions, up to what? Introduced components, loading points, single and double position. These are the registers that MIPS had just to remind you quickly. It has 32, 32-bit integer registers, one of which is hardware preserve. It has 32-bit loading point registers, two of which are paired to get double position when you need. Other than that you have program counter which is implemented by four on sequential instructions, meaning that your instructions are 32-bit in size. There are two special registers high and low for storing multiply, divide, and loss. And this is how you pair up the floating point registers. And we looked at ALU instructions which have classic three operand format, that is two force and one destination. And we looked at several other examples. This is pretty much what it is, you can go and look at the C5's are posted that actually lists what exactly this instruction does. So if you have any confusion, you should see not in English, so there should not be any as easily. But what does this sentence mean exactly, there should not be anything like that. It is a C statement, you should be able to exactly figure out what it is doing. So just I just want to highlight a couple of things, especially I mean we talked about this last time also. So if you look at these two instructions add and add unsigned. And if you look at what they do, they do exactly the same, there is no difference actually. The only thing is that we ignore the overflow in one case, which case does anybody remember? The unsigned case, the unsigned case we ignore the overflow. In the other case we actually take the exception, whenever if your overflow exceptions are set. That is one thing. The second thing is that when you look at the immediate instructions, like add immediate, where you know that one of the operands is an immediate value, like here it is 100. So in this case in the immediate instructions, so there are two variants, add immediate and add immediate unsigned. In both cases, this particular immediate value will be signed extended. So essentially what it means is that again, the only difference between add i and add i u is that in the unsigned case, we ignore the overflow. But in both cases, the immediate concept will be signed extended. No, no, no. You can specify a negative number here, add unsigned. Yes, that is fine. It will be signed extended. So the only, so that this is somewhat confusing, but keep this in mind, the only difference is that in one case, we ignore the overflow in the other case we ignore. It has nothing to do with the signed extension actually. In both cases, we will be doing a signed extension. So it is set less than immediate, it is essentially a comparison. It is taking what it is down to is less than 100 number. So in this case, 100 will be treated as a signed number. So if you specify a negative number here, it will be taken as a negative number. But if you specify a negative number here, it will be signed extended to get a 32 bit operand. But then the whole 32 bit thing will be treated as an unsigned large number. So keep that in mind. So again, yeah, so why are we doing a sign extension or zero extension? Because of course, this is a 32 bit operand. To be able to do the operation, I need to extend this to a 32 bit operand. But usually this is going to be less than 32, because this is going to be part of the instruction, which itself is 32 bits. Clearly this is going to be smaller than 32 bits. And mult and mult unsigned. So again, the same difference. So keep this in mind, arithmetic instructions, all unsigned sign differences that you do not know in one case. So here, the result goes to two specific registers, low and high. In case of division, quotient goes to low, remainder goes to high. And then you have two instructions to move from high and to move from low. So for example, this instruction will copy high into dollar 4. So now, you can actually do conventional arithmetic on the result of your portion, I am sorry result of your division or multiplication. Because low and high do not, you are not allowed to use low and high in any other arithmetic instruction as an operand. So clearly you have to bring it first to the general purpose register, then only you can use that. Any question on this left side, left column, right column. So this is pretty much it actually. So I might have missed out a few, one or two here and there. You can look up the C 5. You will have the exhaustive list of all arithmetic instructions. So the logical side, there really is not much to explain that the mnemonics are self-explanatory and or exonerant and immediate. Again here, we will be doing 0 extension, all logical operations. So these are not sign extension, these are actually 0 extension. Or immediate, exor immediate, shift rate logical, shift rate logical, shift rate arithmetic, this one we discussed last time. Essentially this means that you shift dollar 2 to the 9 by 10 positions while shifting in the sign rate, instead of shifting in zeros. Shift left logical variable, this one has a special property that whatever you mention in dollar 1, so dollar 1 is a shift amount, by how much I should shift. It will only take the lower findings, because the maximum shift amount cannot be more than, cannot be more than 30 to exactly. So it will pick up only the lower findings in dollar 1 and ignore everything else. You can specify a very large number in dollar 1, it is going to ignore everything but the last one. Same for shift rate logical variable, shift rate arithmetic variable. Louis, this one is used to only affect, actually it affects the whole register, but what it does is that it puts 40 in the lower, in the upper 16 bits and 0s out the lower 16 bits in dollar 3. So essentially this one stands for load upper immediate. So we will see the practical application of this. Can anybody guess how I might want to use Unique? What could be a load application for that? Can you guess about that? How do I load a constant in your register? So I want to operate on a constant, what are the options you might have? Suppose I want to do the operation x plus c, where c is a constant, c is a constant known at compiler. So essentially I have this kind of a program, as defined c is some value here and then somewhere in the program I say y equal to x plus c. So compiler knows the value of c. So what are the options do I have? How do I compile this instruction? Can we do add immediate? That is the obvious one to do, add immediate. So by the way remember that in most cases the compiler will generate an add immediate as opposed to add immediate in unsung. Because it will usually generate an instruction where operation is actually turned off or for detection is turned off. So the obvious answer is that why not add immediate? Does anybody see any drawback of using add immediate? So essentially what I will do is I will put x in the register. So let us suppose y is allocated in R 2, then I will generate add i, following the lips, some that is the value of c. Does anybody see any problem with this? Can I do this all the time? Should be what? Should be less in this case. Should be less in this case? Because the instruction is of 32 and the output and other of them will take some storage and for c there will be limited. So when the designers came up with meets encoding they already have allocated some fixed number of bits for encoding an immediate value. So c should be within that range like for example if I say when my immediate value cannot, I am sorry immediate value is encoding 16 bits, then c will be more than 2 to the power 16 minus 1. That is the largest value I can represent. So clearly there is a limitation. What do I do if c is larger than that? What options do I have? How they compile this? Does everybody follow what I am trying to say? Why add i has a problem when c is larger than that? But I cannot of course impose a constraint on my high level language program. I say that oh we are compiling for an architecture for which a constant can be only this much. That is a non sense assumption. So there are lots of ways to compile it for large constants. How do you do that? So what other options do I have? So add i for small constants. What else? And keep it allocated for small constants. Now what do you mean by that? Assign dedicated registers in small constants. How does it get that value? How do you bring that value to that register? You load it and so whenever you need it you bring it from there. So essentially what you are suggesting is that allocate scene memory. And whenever you need the value from memory in the load instruction from memory to the register. Is that what you are suggesting? No. But anyway that is an option. Let me just list it here. Load from memory. What do you have to say? Keep it in that register. Now how does the register get the value? That is the question. There should be one time load and then use that register. One time load. So this is what you are suggesting. You load from memory what you are saying is that I have to keep in that register forever. So maybe you learn in a compiler course that it is not a very good idea of that. Essentially what you are doing is this constant may be used in some localized places in the program. But you are filling it for the entire life of the program which constrain the compiler in the alophane registers. What else can I do? Load from memory. This is a costly operation actually. Memory is slow. So this is often called interpreting a constant at runtime. This particular operation. Even if you know it at compile time, you are actually generating a constant from memory. Which is a very big bad solution. What else can I do? There is no auto increment instruction here in this list. Suppose we can use two instructions instead of one for generating this constant. But no memory operation. Can you do that? How? How do I do that? 16 bits. Which 16 bits? From this constant C. Which 16 bits? Upper 16 bits. Upper 16 bits of C. Which the compiler can calculate at compile time. I can then shift. Shift. Shift can at 16 times and then again load. No. What do you shift by 16 times? The value of C. It will be some 32 bits. Yes. So first of all 16 bits. Let us take an example. Suppose C is 0x12345678. It is 32 bit constant. So first of all what is that? 1234. So I will say Louis. Let us say Dora 1 0x1234. Dora 1. Keep Dora 1. Then shift at 16 bits. Who? Shift what? Shift at C. Shift C. Okay. Yeah. See what I am trying to do? You are trying to get a lower 16 bits? Yeah. Okay. All right. And then do what? Do what? We can get the lower 16 bits. I want Dora 1 to contain C. Right? First you get the lower bits and then shift right and then put the... Can you give the instruction sequence exactly? So here we can get 0x577 and... When? Shift right. No. What is the instruction? You have to pick one from this list. Be very, very, very specific. SLL. SLL. SLL. What are you shifting? Shift. Shift shift amount. What is Dora 2? Dora 2 is... Dora 2 is? AP is Dora 1 actually. So after 3? Yes. Okay. I will put an SLL. Okay. Let's see what you are saying. SLL? RL. Oh, sorry. SRL. Yeah. SRL? I said Dora 1. Dora 1? No, sir. Here we will... Dora 1 again and... Dora 1, Dora 1? 16. 16. 16. 16. That will have a... Sorry? 34. 34. See. So now the 1, 2, 3, 4 will come in this one. No, wait a minute. Is that all? So now the... Now what is the content of Dora 1? Can somebody say after this? 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. 00001234. Let's go one by one. What is the content of Dora 1 after this instruction? 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. 1.3. then what you say again I want this value remember that. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . that will give you 5, 6, 7, 8. Then you shift this 5, 6, 7, 8 into 16, then I do a r 2. Can I, does not even follow what he is saying. So, he is saying I will let you write it and optimize it. Is that what you are saying? Can we optimize it? Sir, we do a Louis first instruction and then do a add 5, 6, 7, 8 add dollar 1, dollar 1, dollar 1, 5, 6, 7, 8. Add immediate you mean? Yes sir. Right, I can do that. So, I can remove these, right, that will give you the same outcome. So, what else can I do? Can I use anything else other than add 1, 6, 7, 8 from this list? This will not give the same. This will not give the same thing, why? Because 1, 2, 3, 4, and 5, 6, 7, 8 as the over this. So, dollar 1 will have this one at the end of Louis and 5, 6, 7, 8 will get added here. Can I use anything else other than adding here from this list? We are almost there, sorry, or r. So, this is what a good idea is to do this, right. So, what I am going to do is take a, I can take a 1, 2 and 3. So, I will take a 1, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 10, 11, 12, 13, 14, 14, 15, 16, 16, 18, 18, 19, 19, 20, 20, 23, 24. Can we do this? No, this constant will go into the immediate field, though same 16 bits, floating point operation. These operate on floating point registers, suppose both single and double positions, they have no hardware at zero register. So, you have to interpret 0, I typical instructions at sub model div move where essentially you move from one protocol register to another negate absolute value CVT is a precision conversion. So, if you want to convert from single position to double position essentially this is used when we are trying to have typecasting in the higher level language. For example, the typecasting in a flow flow down, compiler generated CVT instruction or vice versa. MFC, MTC move between floating point and integer register. So, this C might be a little non-intuitive why are they saying move from C and move to C. The reason is that can you guess why? What does it see stand for? Because I would have actually expected that it would say move from F and move to F right MFA for MTF. What is the C? What is it referring to? It is now it is not conversion it is moving from something that is what the C stands for not cash. What can you think of any other word related to microprocessors starts with C. So, the floating point unit actually was a coprocessor in the early mids processors. So, the first instruction MFC moves from a floating point register to an integer register and MTC move from an integer register to a floating point register and this is again generated whenever you try to do typecasting in a high level language. Suppose you are cast an initial grab into a float the compiler will generate one subject. Marlton div sorry Marlton div do not use C. So, this is the C. So, this is the C. So, this is the C. So, this is the C. So, this is the C. So, this is the C. So, this is the C. So, this is the C. So, this is the C. So, we use the Laplace specifications to boat in RFC language. So, this is the C blocking which is much larger than MTC. So, here we have this A, yes you have this the A is strictly written A, yes you have B, yes you have B. Ok, so treaties in this RFC for Ka revived So, you have names right, you can name any point registers. So, we have this coding point gel properties, you can name them. So, that takes care of your integer logic, coding point arithmetic. Now, we come to the memory side of it. So, load store operations there is only one addressing mode supported. So, we looked at them in the past. So, which supports exactly one and that is the displacement addressing mode. Always sign extended. So, essentially you have a. So, it looks like this. So, you have a base register and you have a displacement and the displacement is always sign S. So, most loads and stores are aligned except, we will talk about this load word left load word right LWLWR and similarly store word left and store word right. So, we will talk about those. So, these are the only exceptions which are non aligned loads and stores and those four instructions also allow you to access some registers. So, part of the register while keeping the rest on the board. Loads are supported for signed and unsigned data, unsigned loads 0 extended loaded value. So, keep in mind that the signed and unsigned loads are loads differed in this only. So, once you reach the data from memory whether you sign extend the data or 0 extend the data displacement is always sign extend. Suppose three sizes byte half or LWLWR double load is supported in 64 bit ISA. So, 32 bit ISA does not have any double load instructions. So, byte load there are two as we have already mentioned one is load byte signed. Do not write the sign S here explicitly and load byte unsigned. So, this is what it looks like it takes essentially one source register, one displacement constant and a target register. So, displacement in both cases will be signed extended meaning that if you specify a negative displacement it will be treated as a negative displacement it will be subtracted from this actually. And the final value that you load will be signed extended in this case to fill up a 32 bit register whereas, this one will be 0 extended. Half-word load LH and LHU load half-word and load half-word unsigned. What load load what there is no unsigned framework why is that? Exactly. So, it already returns 32 bit value there is nothing to extend actually. So, even if we had a load word unsigned it would be negative. Similarly, we have a byte store. So, there is no unsigned version of store you want to store a byte. So, what you do is you take two source registers dollar 2 will be used as the base register for address which will be added to the displacement this will be signed extended. And you take the value from dollar 3 you take the least significant byte of dollar 3 and send it to this particular address. Similarly, you have half-word store SH and word store SW. So, SW would store the entire register dollar 2 at this particular address. So, you can you can exactly figure out how this instruction actually execute in the C file again. You can go and look up actually which byte it extracts and all this. Immediate is not shifted by load store size. So, that is very important to understand because in many books you will find that not with respect to MIPS, but in general they say that this number 27 will actually be multiplied by something before adding to dollar 280 MIPS does not do that. We will just take this displacement as it is we will add it to this base generate the address whatever the address will be used to load the store. So, that is what is mentioned here. Immediate displacement will not be shifted by load store size. It is just signed extended and added to the base register content. In addition you have floating point load store. For example, you have LF dollar F 160 lower 22. So, these instructions are written in the tutorials in the sense that it will actually have an integer register source for generating the address and a floating point register target. So, you can imagine a store floating point instruction would actually have a floating point register source and an integer register source. So, these actually interface with the both integer pipeline and the floating point pipeline. So, that way they are a little harder to implement. But otherwise they execute exactly in the same way. This will be signed extended LF dollar 22 get the address known to value 4 and here of course, you do not have these unsigned by power 4 load all these things. You have only 2 one is LF that is the single position load one is LF dot B. Depending on that you will load either 32 bytes from here or 64 bytes from here. So, in some cases the address is known at compiler happens mostly for statically allocated global vendors. So, compiler knows the exact address of the address. So, the question is why should I have to then interpret the address that is generate the address at runtime. So, why cannot they use it directly. So, how do you have direct address. So, suppose I want to load from address 0 x 1 2 3 4 5 6. So, this is exactly where we comes very very handy. So, what you do is you first load the upper 16 bits that is 0 x 1 2 and then you are with the lower 16 bits and what you have essentially dollar 2 is address. So, you can see 0 dollar 2 boom right could save all instructions by using non-zero displacement I could do also this that is also it is going to be better because it saves one instruction. What if the address is 0 x 7 8 9 8 8 c what is the special about that address. So, that is essentially the question is asking you is that can I use the same thing for this address answer must be no why is that. So, what I am saying is that I cannot really say 0 e dollar 2 is 0 x 7 8 and load of dollar 4 is 0 x 9 8 c dollar 2 I cannot do that. This is 16 bits. 9 a b c that 6 bits where this person is I am sorry I have not mentioned that we come to that the exact input yes. So, it is a 16 bit immediate value in all cases. So, any constant that goes into the instruction we cannot exceed 6 bits, but it is ok right 9 a b c 6 bits, but this is going to be wrong that is the problem yes. So, 9 a b c you will be saying it is ok thank you. So, somebody is paying attention that is pretty clear ok. So, yes 9 a b c what is the m s b of 9 a b c the most significant bit 1. So, remember that displacement is going to be sin extended. So, if sin extend 9 a b c you fill up with all 1s. So, the address that we will get will not be this actually we add up to this right. So, you cannot do this what should you do what should I do here then how do I get this done can I use this no yes is the or I find 9 a b c here. Yeah. Yeah. Why? It is not time. 9 a b c 8 value. Yeah. And it has to be extended to get a 32 bit operator. So, it is not time. What is our sign? How do you figure out where is the sign. And of course I do not have any problem with this one here. Now, the problem is here you shift it shift to here. So, I have an immediate value which is 9 a b c here, but this is ok why? 0 extended. Who is in extended? Why? Why not sin extended? Because it is logical. Logical operation. Logical operation. Thank you. So, logical operation of immediate values are always 0 extended. So, this scheme is ok. So, compiler has to figure out by looking at this address which one can I pick this one or this one. So, in most cases you will be able to pick this one, but in some cases you will be able to pick this one depending on the address. So, remember that it cannot really figure out by looking at how big the address is because 7 a b c is ok actually. So, you cannot just make a comparison by looking at the address range, you have to look at only these 16 minutes and ask is the MSD 1 or 0. If it is 1 it will generate this code, otherwise it will generate this code. Question? So, keep this in mind automatic immediate some sin extended logical immediate are 0 extended. Now, lower word left and lower word right. So, let us try to understand what they do. Let us take this particular example of course, this is not legitimate mix because you cannot really mention the address like this. So, this is just an example. So, I am trying to do something from an address which is 1, 2, 3, 4, 5, 7 all right and it looks like a load operation and I want some value in the lower word. So, let the word containing this byte address be w. So, what does that mean? So, 1, 2, 3, 4, 5, 7 right. So, let us see what is the word? We have 4 bytes and 5, 7, 5, 6, 5, 5, 5, 4, 5. So, we can get. So, you have 5, 4 here, 5, 5 here, 5, 6 here, 5, 7 here right. Extract the bytes contain by w that start from this address. So, we start here. So, in this case it is going to be only 1 byte right. We will say extract the bytes contain by w that start from this address. Put these bytes in this case just 1 byte this one. In the upper portion of drawer 4 and leave the remaining bytes unchanged. So, essentially at the end of this particular instruction with drawer 4, we have this byte copied here. Evaluating the bytes remain unchanged. This is load word left load word left of drawer right. Starting from the address take the bytes load word for the left end of drawer 4, load those bytes load the left end of power. This is here typically what he is doing. So, this is the only instruction. So, these are the only instructions in MIPS that allows you to do unaligned more accesses in unaligned more accesses. Because an aligned more address would have given these address that allows you to modify a portion of your instruction. Because everything else would actually overwrite all of them completely. It preserve the load 3 bytes. So, LWR does exactly the same thing just in the opposite direction. So, let us take this example it says 1 2 3 4 5 a. So, let us see what is W in this case 1 2 3 4 5 a. We have 5 9 5 8 5 8 5 8 is on the B end 5 9 5 8 5 B. These are what containing this byte address. Extract the bytes contained by W that end at this address that end at this address. So, looking at these bytes 3 bytes put these bytes in this case 3 bytes. In the lower portion of drawer 4 and leave the remaining bytes in this case the upper byte unchanged. So, at the end of the execution drawer 4 will have these 3 bytes copied on this side leaving this one unchanged. Why are these instructions at all involved or what circumstances will generate these instructions. Can you think of a use case? Think about using both of these together. Yes, what if I teach these two words W and let W and W point. If we are taking these two operations together. What is that? So, let us teach W and W point. So, we have 54. See if I use these two instructions one after another. I will have copied it what I have done. So, I would have copied this portion into drawer 4. Is that clear to everybody at this? If I use these two instructions one after another I would have copied those four bytes into drawer 4. Why do I have to do it in this way? Is there any other way of doing it? Once you realize that answer is no you will then immediately see the use of these instructions. Is it equal? It is not variable length I am just copying a word actually. I am copying a word spanning 57, 58, 59, 5A into a register that is it. Why cannot you use load word in this case? It is not a line. Yes, exactly. So, it is very useful when you want to copy a word from an unaligned address. These are only going to do it in bits. There is no other way actually. What kind of programs might generate unaligned word accesses? If I ask you to write a C program that compiles into a W and a W are in structures. You sort of write a W and a W and a W in a W. So, you have to do it in a W and a W. I will do it in the same way in the same way. If you want to do it in a W you have to I want to extract some characters from some arbitrarily places. The most efficient code will be with these two instructions. So, why it will be always that I am here, why it will be? 1 by the line. 1 by the line, exactly right. So, every axis will be a line. Every axis will be a line, exactly. So, one way to do that will be to read one byte at a time. Yes, but that will take 4 instructions to read 4 bytes and I can use just 2 to load 4 bytes like this. Yes of course, you can synthesize it using bytes 1 byte at a time, but this is going to be much more efficient. So, I will actually today I will post on the code . So, one C program and of course, it is a simple C program. It tries to do something of itself, it takes a string and tries to extract some arbitrary characters. You see that these two instructions are getting generated. So, what about unaligned 16 bit, unaligned half. No, we cannot do that. You have to do not want a new shift. For example, if you want to load half word 57, 58, you will not do that. You load this one and then do a shift to get that. Any question? Control transfer. So, there are jump instructions. So, these are essentially un-conditional jumps and procedure drops. They use absolute address because the compiler knows address. So, here by procedure call, I mean direct procedure calls for indirect calls. So, MIPS ISA offers 26 bits to encode the absolute target. So, shift is started to left by 2 bits because your instructions are 4 byte instructions. So, any legitimate PC will have last 2 bits 0. So, essentially when you are specifying a branch target, there is a meaning of including those 2 bits also because they are implicitly 0. So, what you do is you specify 26 bits, which can give you a 28 bit target by shifting into 0s and borrow the upper 4 bits of the next PC that is PC plus 4 to form the complete 32 bit target. So, essentially what I am saying is that suppose at a particular PC, you have a jump instruction. It says jump to some level and this level is known at compile time. That is what we are talking about. Unconditional data jumps. What if you do it? The compiler will do is it will take the level, shift out the lower 2 bits because the lower 2 bits are always 0 for any legitimate program counter. And then what we will do is it will take 26 bits. 26 bits are allowed only. It cannot be more than that, which means there is a span of this level. How far you can jump? There is a limit to that. So, this is how it computes the final target. It takes the upper 4 bits. So, 28 bits will give out to be upper 4 bits to form a legitimate PC. This is the 32 bits. So, it takes the upper 4 bits from the next PC, PC plus 4 and it shifts in the target in the lower 28 bits. So, procedure call instruction known as jump and link in MIPS. So, this is JAG that is the m 1 it used for procedure call jump and link saves a return PC, which is PC plus 8. Why is PC plus 8 and not PC plus 4? When you make a procedure call, it should return to the next instruction. So, it jumps one instruction down. So, it comes back in PC plus 8 not PC plus 4. So, does anybody know why? So, it will save some where means it will save to the data address. So, it will take more bytes. No, we are saying the data address is PC plus 8. No, it is nothing to the standard. I am saying I am at a JAG instruction which says JAG level and I am a PC here. The next instruction is PC plus 4. I should be returning here. So, a return address should be PC plus 4, but what MIPS does is it says the return address is PC plus 8. That is PC plus 4 and it will also have some return address. This is return address. We are not talking of the return value of the function. That will call the stack of where it will be. We are just trying to figure out where I should resume my execution when the function completes. And what MIPS does is it is PC plus 8. It skips over one instruction. PC plus 8 is here the next one. So, that is just a name. It is linking with the procedure. So, PC plus 4 is already in the pipeline. PC plus 4 is already in the pipeline. So, the next cycle is PC plus 8. Next cycle, no. I am waiting real cycles to complete that procedure. PC plus 8 should not be the pipeline. It cannot be PC plus 8. So, it saves the return address which is PC plus 8 in a fixed register, which is dollar 31. This is known as the jump return register or often called the link register. So, that is your procedure call instruction. So, the label is encoded exactly the same. So, how far can you jump? 2 to the power of 26 instructions. So, that is why jump span. Which is a very large actually span. 2 to the power of 26 is what? 64 million instructions that you jump. Indirect jumps where target is not known that is procedure return or case switch or procedure call by a function pointer. Uses a jump register instruction or jump and link register instruction. So, there are 2 instructions to do that. One is J R another one is J R. Both take a register operant for the target is found. So, for example, here when you return from a function where your returning is not known here. Because you may return to many different places depending on from where you are called. So, it says J R dollar 31. Remember that we use dollar 31 to save the return address. You will actually take the return address from here. Alright, I will stop here. So, next time we will try to demystify these 2 dimensions. Why this is?