## LSU EE 4720 -- Spring 2015 -- Computer Architecture
#
## MIPS Floating Point


## Under Construction
#
# Time-stamp: <23 January 2015, 9:11:53 CST, koppel@sky.ece.lsu.edu>

## Contents
#
# MIPS Floating-Point Instructions

## Objectives
#
# Floating Point
#  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.


## 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  Need for format conversion.


## 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
#
# Briefly here, in detail later.
#
#
 ## Arithmetic Operations
#
# Add double-precision (64-bit) operands.
#
# MIPS:  add.d $f0, $f2, $f4
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
#
# Load double (eight bytes into two consecutive registers).
#
# MIPS:  ldc1 $f0, 8($t0)
#
#
 ## Move Between Register Files (E.g., integer to FP)
#
# MIPS:  mtc1   $t0, $f0

 ## Format Conversion
#
# Convert from one format to another, e.g., integer to double.
#
# MIPS:  cvt.d.w  $f0, $f2
#
#
 ## Floating Point Condition Code Setting
#
# Compare and set condition code.
#
# MIPS:  c.gt.d $f0, $f2
#
#
 ## Conditional Branch
#
# Branch on floating-point condition.
#
# MIPS:  bc1f TARGET   # Branch coprocessor 1 [condition code] false.

 ## FP Load and Store


        # MIPS
        #
        # 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


 ## Move Instructions

        # MIPS
        #
        # Move to coprocessor 1
        mtc1 $t0, $f0      # f0 = t0   Note that destination is *second* reg.
        #
        # Move from coprocessor 1.
        mfc1 $t0, $f0


 ## Data Type Conversion

        # Convert between floating-point and integer formats.
        # NOTE: Values don't convert automatically, need to use these insn.

        # MIPS
        #
        # To: s, d, w;  From: s, d, w
        #
        # cvt.TO.FROM fd, fs
        #
        cvt.d.w $f0, $f2     # $f0 = convert_from_int_to_double( $f2 )

 ## Setting Condition Codes

        # In preparation for a branch, set cond code based on FP comparison.

        # MIPS
        #
        # 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.ge.d $f0, $f2    # CC = $f0 >= $f2
        bc1t TARG2          # Branch if $f0 < $f2
        nop
        # Reachable?


 ## FP Branches

        # MIPS
        #
        # Branch insn specifies whether CC register true or false.
        #
        bc1t TARG
        nop
        #
        bc1f TARG
        nop