简体   繁体   中英

Why does the I-type immediate get extended from 16 bit to 32 bit?

I am preparing for a University Exam and i don't understand why the immediate field in the I-type gets extended from 16 bit to 32 bit is there an explanation I need to know or is it just something that you have to know that happens in the architecture without knowing why?

Also while calculating the branch address

PC <– PC + 4 + (sign_ext(Imm16) << 2)

Why does the immediate get shifted by 2?

As already answered in the many comments...

Although MIPS does have a 16 bit instruction format the instruction set everyone is familiar with is a 32 bit fixed length instruction set, on aligned boundaries.

The various operations use 32 bit operands.

You cannot have a 32 bit immediate in an instruction set that is fixed 32 bits; there would be no bits left for an opcode. So MIPS has different instruction formats with different immediate sizes to balance a rich array of instructions without as much pain at using immediates or forcing all immediates to be loaded from a nearby pool. Worst case you can fall back on that but for a good number of things you can use the instructions as designed.

So the immediate fields are much less than 32 bits, but the operands they represent are generally 32 bits, so they need to be extended in some way, either shifted 16 and padded with zeros at the bottom or extended from the top unsigned or not (speaking generically not just for this type of mips) to make a 32 bit value.

How the immediate is used should be looked up per instruction in the documentation.

Why do branches shift the immediate by 2?

The instructions are on aligned 32 bit boundaries which means the lower 2 bits are always zero. If you encoded those zeros into the immediate you would always have to make them zero and basically lose four times the possible range of your pc relative branch. Think of the immediate in this case to be the number of INSTRUCTIONS I want to branch rather than number of BYTES of address.

Being signed allows for forward or back branching.

nextPC <– PC + 4 + (sign_ext(Imm16) << 2)

The + 4 is part of a pipeline illusion, different cores have their own pipe designs so there must be a standard to have the ISA not be crazy to use (very typical design choice across many ISAs to have the PC at execution time point at the next instruction). So nextPC is the PC of the next instruction plus the signed offset number of instructions in the immediate (by shifting left two making the lower two bits zero). If the condition is met or if unconditional (I don't know all the I format instructions, I don't need to in order to answer this question) then nextPC is used by the logic otherwise PC + 4 is used for the next instruction.

Edit

Yes, you are correct; the sign extension does already make it a 32 bit value. The additional shift is to maximize the range that the branch can take, giving us four times as far forward or backward to branch with this instruction format. The upper sign extended bits are all either 0s or 1s and there are more than 2 bits of extension so shifting the temporary 32 bit value two more bits does no harm to that value.

With a 16 bit signed immediate if I wanted to not do that shift of two then 0x00007FFC is the maximum distance I could branch forward and to be a valid instruction the lower two bits would have to be zeros. With the shift I can now branch 0x1FFFC forward and I can use all of the immediate bits.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM