## LSU EE 4720 -- Spring 2025 -- Computer Architecture # ## MIPS Floating Point ## Contents # # MIPS Floating-Point Instructions ## Objectives # # Floating Point # Understand how FP and integer are separated. # Read and write MIPS programs using floating point instructions. ## Introduction # # Floating Point (FP) is Different # # - Separate data format. (Of course.) # - Separate instructions. (Makes sense.) # - Separate registers. (Why's that?) # # Reasons that FP is Different # # - Floating-point (FP) operations take longer than integer operations. # - FP hardware is more costly. # - FP operations rarely performed on integers and vice versa. ## Sample Problems # # The following are problems about using floating-point instructions, # but not about how to implement them. # # Spring 2018 Midterm Exam Problem 3. # Spring 2018 Midterm Exam Problem 4c. # Spring 2017 Midterm Exam Problem 4. # Spring 2016 Midterm Exam Problem 3a ## Quick Example # :Example: # # Load two FP values from memory, add them together, and write result. lwc1 $f1, 0($t1) # Load word coprocessor 1. lwc1 $f2, 4($t1) add.s $f3, $f1, $f2 swc1 $f3, 8($t1) ## Note # # - Address specified in same way as integer loads and stores. # - "f" registers for FP values. # - Different instruction for add (ends with ".s"). ## Differences Between FP and Integer Instructions # # o Separate set of registers. (f0-f31) # o Separate instructions to operate on those registers .. # ... for arithmetic (add) ... # ... and loads and stores. # o THE NEED FOR FORMAT CONVERSION. # (sorry for raising my voice, but I didn't want you to forget) ## Registers # ## MIPS Registers # # MIPS has four sets of coprocessor registers. # The integer (GPR) registers are NOT one of the four sets. # Each set has 32 registers. # # Co-processor 0: Processor and system control. # Co-processor 1: MIPS-32 floating-point # Co-processor 2: Reserved for special-purpose designs. # Co-processor 3: MIPS-64 floating-point # ## Separate Floating Point Registers # # A feature of many RISC ISAs. # Eases implementation. ################################################################################ ## Floating Point Summary ## MIPS Floating Point # # Supports IEEE 754 Single- and Double-Precision FP Numbers # # Floating point handled by co-processor 1, one of 4 co-processors. # # MIPS floating point registers also called co-processor 1 registers. # MIPS floating point instructions called co-processor 1 instructions. # # Registers named f0-f31. # Load, store, and move instructions have "c1" in their names. # Arithmetic instructions use ".s" (single) or ".d" (double) , or ".w" (int) # /completers/ to indicate operand type. # ## Types of Floating-Point Instructions # # ## Arithmetic Operations # # MIPS has basic operations: add, sub, mul, div. # Some ISAs include trig, exponential, etc. # # Operands can be single precision (32 bits) and double precision (64 bits). # Suffix indicates operand precision (and type) # .s Single Precision # .d Double Precision # .w Thirty-two Bit Integer (used in conversion instructions). # Single-Precision Operations # add.s $f8, $f9, $f10 # f8 = f9 + f10 # No tricks, straightforward, easy. sub.s $f8, $f9, $f10 mul.s $f8, $f9, $f10 div.s $f8, $f9, $f10 # Double-Precision Operands # # MIPS-I co-processor I (FP) registers are 32 bits .. # .. to perform double-precision operations .. # .. registers used in pairs .. # .. the first register of a pair is an even-numbered register. add.d $f0, $f2, $f4 # {$f0,$f1} = { $f2, $f3 } + { $f4, $f5 } add.d $f0, $f2, $f5 # Illegal in MIPS 32 ## Immediate Operands # # MIPS floating-point instructions do not have immediate operands. # # Many other ISA's FP instructions lack immediate operands. ## Load and Store # # Move values from memory to FP registers and from FP registers to memory. ## Instructions # Load word in to coprocessor 1 lwc1 $f0, 4($t4) # $f0 = Mem[ $t4 + 4 ] # # Load double in to coprocessor 1 ldc1 $f0, 0($t4) # $f0 = Mem[ $t4 + 0 ]; $f1 = Mem[ $t4 + 4 ] # # Store word from coprocessor 1. swc1 $f0, 4($t4) # $f0 = Mem[ $t4 + 4 ] # # Store double from coprocessor 1. sdc1 $f0, 0($t4) # Mem[ $t4 + 0 ] = $f0; Mem[ $t4 + 4 ] = $f1 # :Example: # lwc1 $f1, 0($t1) lwc1 $f2, 4($t1) add.s $f3, $f1, $f2 swc1 $f3, 8($t1) ## Move Between Register Files (E.g., integer to FP) # # MIPS: mtc1 $t0, $f0 ## Move Instructions # Move to coprocessor 1 mtc1 $t0, $f0 # f0 = t0 Note that destination is *second* reg. # # Move from coprocessor 1. mfc1 $t0, $f0 # :Example: # # Add 1.0 to value in $f2, put sum in $f3. lui $t1, 0x3f80 # Single-precision 1 0x3f800000 mtc1 $t1, $f1 add.s $f3, $f1, $f2 # :Example: # # Add 12345 to value in $f2, put sum in $f3. lui $t2, 0x4640 # 12345 0x4640e400 ori $t2, $t2, 0xe400 mtc1 $t1, $f1 add.s $f3, $f1, $f2 ## Format Conversion # # Convert from one format to another, e.g., integer to double. # # MIPS: cvt.d.w $f0, $f2 # # ## Data Type Conversion # Convert between floating-point and integer formats. # NOTE: Values don't convert automatically, need to use these insn. # To: s, d, w; From: s, d, w # # cvt.TO.FROM fd, fs # cvt.d.w $f0, $f2 # {$f0,$f1} = convert_from_int_to_double( $f2 ) # :Example: # addi $t1, $0, 1 # Integer 1 mtc1 $t1, $f1 cvt.s.w $f1, $f1 add.s $f3, $f1, $f2 addi $t1, $0, 1 # Integer 1 mtc1 $t1, $f1 cvt.d.w $f6, $f1 add.d $f30, $f6, $f2 ## Floating Point Condition Code Setting # # Compare and set condition code. # # MIPS: c.gt.d $f0, $f2 # # ## Setting Condition Codes # In preparation for a branch, set cond code based on FP comparison. # Compare: fs COND ft # COND: eq, gt, lt, le, ge # FMT: s, d # # c.COND.FMT fs, ft # Sets condition code to true or false. c.lt.d $f0, $f2 # CC = $f0 < $f2 bc1t TARG # Branch if $f0 < $f2 nop c.le.d $f2, $f0 # CC = $f2 <= $f0 bc1t TARG2 # Branch if $f0 >= $f2 nop # Reachable? ## Conditional Branch # # Branch on floating-point condition. # # MIPS: bc1f TARGET # Branch coprocessor 1 [condition code] false. ## FP Branches # Branch insn specifies whether CC register true or false. # bc1t TARG nop # bc1f TARG nop ## Using Floating-Point Constants # # MIPS floating-point instructions do not have immediate operands. # # Consider this integer instruction: addi $t0, $t1, 2 # Two is provided as an immediate. # This is NOT valid MIPS: add.s $f0, $f1, 2 # ILLEGAL MIPS. Yes, it would be nice. # Constants, such as 2, must be provided using instruction sequences. # # Three methods to provide FP constants. # # - Load FP constant from a table in memory. # This method is commonly used by compilers. # - Load FP constant using integer immediate instructions and move to FP. # - Load integer constant using int immediate insns, convert to FP. # :Example: # # Load FP constant from a table: .data # Compiler (or human) prepares table TWO: .float 2.0 # Assembler converts 2.0 to IEEE 754 single. TWO_POINT_TWO: .float 2.2 TWO_POINT_TWO_AS_A_DOUBLE: .double 2.2 .double 4.4 .text la $t7, TWO lwc1 $f2, 0($t7) # Load 2. lwc1 $f1, 4($t7) # Load 2.2 add.s $f0, $f1, $f2 # :Example: # # Load FP constant using integer immediate instructions and move to FP. lui $t1, 0x4000 # Single-precision 2 0x40000000 mtc1 $t1, $f2 add.s $f0, $f1, $f2 # # Note: Some FP constants require a two instruction sequence. # :Example: # # Load integer constant using int immediate insns, convert to FP. addi $t1, $0, 2 mtc1 $t1, $f2 cvt.s.w $f2, $f2 add.s $f0, $f1, $f2