Integer Multiplication, Division Arithmetic shift Twice the number of places MIPS multiply unit. mult, multu Significant bits mfhi, mflo, div, divu Arithmetic shift. sra madd, maddu, msub, msub mul, mulo, mulou Textbook: Appendix A Central Connecticut State University, MIPS Tutorial. Chapter 14.
Review: MIPS programming model MIPS contains: Integer arithmetic processor Floating point arithmetic processor Whole system’s Control Processor In this model from the textbook we can see several additional groups of MIPS instructions : Integer Multiplication Division instructions. Floating point arithmetic instructions. System Control instructions
Twice the Number of Places The product of two N-place decimal integers may need 2N places. This is also true for numbers expressed in any base. In particular, the product of two integers expressed with N-bit binary may need 2N bits.
Significant bits The significant bits in a positive or unsigned number represented in binary are the most significant 1 bit (the leftmost 1 bit) and all bits to the right of it. For example, the following has 23 significant bits: 0000 0000 0100 0011 0101 0110 1101 1110 The significant bits in a negative number represented in two's complement are the most significant 0 bit (the leftmost 0 bit) and all bits to the right of it. For example, the following has 23 significant bits: 1111 1111 1011 1100 1010 1001 0010 0010 To ensure that a product has no more than 32 significant bits, ensure that the sum of the number of significant bits in each operand is 32 or less. We will mostly write programs that keep the result under 32 bits in length. When this is true, the result of a multiplication will be in lo How to keep the result of multiplication in 32 bits ? How large will be the operands in that case ?
MIPS Multiply Unit The multiply unit of MIPS contains two 32-bit registers called hi and lo. These are not general purpose registers. When two 32-bit operands are multiplied, hi and lo hold the 64 bits of the result. Bits 32 through 63 are in hi and bits 0 through 31 are in lo. 31 0 31 0 63 32 31 0
mult , multu There is a multiply instruction for unsigned operands - multu and a multiply instruction for signed operands (two's complement operands) - mult. Integer multiplication never causes a trap. Note: with add and addu, the operation carried out is the same with both instructions. The "u" means "don't trap overflow". With mult and multu, different operations are carried out. Neither instruction ever causes a trap. Will be different result for mult and multu if I use the same $s and $t for both?
mult , multu If we treat the binary patterns as two’s complement then 2x-3 should be equal to -6 – 11010. So we should use mult to get the correct two’s complement result. If we treat the binary patterns as unsigned numbers then 2x5 should be equal to unsigned 10. So we should use the unsigned multiplication. In this case multu will do the task.
The mfhi and mflo Instructions There are two instructions that move the result of a multiplication into a general purpose register: ## Program to calculate 5 × x – 74 #### Register Use: ## $8 x ## $9 result .text .globl main main: ori $8,$0,12 # put x into $8 ori $9,$0,5 # put 5 into $9 mult $9,$8 # lo <-- 5x mflo $9 # $9 = 5x addiu $9,$9,-74 # $9 = 5x - 74 mfhi $d # d <-- hi. Move From Hi mflo $d # d <-- lo. Move From Lo
div “/” and mod “%” in C 9 div 4 = 2 remainder 1: int 9 / 4 = 2 Example from K&R: printf ("\n9 div 4 = 2 remainder 1:\n"); printf ("int 9 / 4 = %d\n", 9 / 4); //Quotient -> (lo) printf ("int 9 % 4 = %d\n", 9 % 4); //Remainder -> (hi) 9 div 4 = 2 remainder 1: int 9 / 4 = 2 int 9 % 4 = 1
The div and the divu Instructions With N-place integer division there are two results an N-place quotient and an N-place remainder. With 32-bit operands there will be (in general) two 32-bit results. MIPS uses the hi and lo registers for the results: div $s,$t # lo <-- s div t # hi <-- s mod t # two's complement divu $s,$t # lo <-- s div t # unsigned 9 4 1 2
Example ## Program to calculate (y + x) / (y - x) #### Register Use: ## $8 x, $9 y ## $10 x/y quotient, $11 x%y remainder .text .globl main main: ori $8,$0,8 # put x into $8 ori $9,$0,36 # put y into $9 addu $10,$9,$8 # $10 <-- (y+x) subu $11,$9,$8 # $11 <-- (y-x) div $10,$11 # hilo<--(y+x)/(y-x) mflo $10 # $10 <-- quotient mfhi $11 # $11 <-- remainder
Shift Right Arithmetic The problem is that a shift right logical moves zeros into the high order bit. This is correct in some situations, but not for dividing two's complement negative integers. An arithmetic right shift replicates the sign bit as needed to fill bit positions.
The madd, maddu, msub, msubu Instructions Multiply registers rs and rt and add the resulting 64-bit product to the 64-bit value in the concatenated registers lo and hi. madd $8, $9 # Multiply add maddu $8, $9 # Unsigned multiply add Multiply registers rs and rt and subtract the resulting 64-bit product from the 64-bit value in the concatenated registers lo and hi. msub $8, $9 # Multiply subtract msubu $8, $9 # Unsigned multiply subtract
Different multiplication examples ori $8, $0, 0x7FFF # Big numbers multiplication sll $8, $8, 16 ori $8, $8, 0xFFFF ori $9, $0, 0x7FFF sll $9, $9, 16 ori $9, $9, 0xFFFF mult $9, $8 madd $8, $9 # No yet overflow madd $8, $9 # Sign is changed 2's c.overflow but not trap maddu $8, $9 # No yet overflow maddu $8, $9 # Unsigned overflow but not trap # msub $8, $9 # msubu $8, $9 mul $10, $8, $9 # 32 bit multiplications. Without overflow mulo $10, $8, $9 # With 2's complement overflow detection and trap mulou $10, $8, $9 # With unsigned overflow detection and trap