Понятие о сопроцессорах. FPU
- Сопроцессоры:
- Сопроцессор 1 - FPU
- Сопроцессор 0 - управления
- Стандарт IEEE 754
Mars -> Tools -> Floating Point Representation
- FPU MIPS
- MIPS поддерживает числа с плавающей точкой одинарной и двойной точности в IEEE-формате.
- Архитектура MIPS предусматривает наличие тридцати двух 32-битных регистров для чисел с плавающей точкой "$f0–$f31". Это не те же самые регистры, которые мы использовали до сих пор.
- Числа двойной точности (64-битные) размещаются в парах 32-битных регистров, так что для операций с такими числами доступны только 16 четных регистров "$f0, $f2, $f4, ..., $f30".
- В соответствии с соглашением, принятым в архитектуре MIPS, у этих регистров разное назначение:
Название
Номер
Назначение
$fv0–$fv1
0, 2
Значение, возвращаемое функцией
$ft0–$ft3
4, 6, 8, 10
Временные переменные
$fa0–$fa1
12, 14
Аргументы функции
$ft4–$ft5
16, 18
Временные переменные
$fs0–$fs5
20, 22, 24, 26, 28, 30
Сохраняемые переменные
- Код операции у всех команд с плавающей точкой равен 17 (10001 2 ). Для определения типа команды в них должны присутствовать поля funct и cop (от англ. coprocessor). Ниже показан формат команд типа F, используемый для чисел с плавающей точкой.
op
cop
ft
fs
fd
funct
6bits
5bits
5bits
5bits
5bits
6bits
- Команды одинарной и двойной точности различаются суффиксом в мнемонике (.s и .d соответственно). Команды с плавающей точкой включают сложение (add.s, add.d), вычитание (sub.s, sub.d), умножение (mul.s, mul.d), деление (div.s, div.d), изменение знака (neg.s, neg.d) и вычисление модуля (abs.s, abs.d).
- Регистры с плавающей точкой загружаются из памяти и записываются в память при помощи команд lwc1 и swc1 соответственно. Эти команды перемещают по 32 бита, так что для работы с числами двойной точности необходимо использовать по две такие команды.
- В тех случаях, когда ветвление зависит от условия, вычисляемого с использованием чисел с плавающей точкой, оно делится на две части. Сначала команда сравнения устанавливает или сбрасывает специальный флаг условия fpcond (от англ. floating point condition flag, флаг "0" "Coproc 1" в Mars). После этого команда ветвления проверяет этот флаг и в зависимости от его состояния осуществляет переход. Команды сравнения включают команды проверки на равенство (c.seq.s/c.seq.d), проверки на то, что один операнд меньше другого (c.lt.s/c.lt.d) или меньше или равен другому (c.le.s/c.le.d). Команды ветвления bc1f и bc1t осуществляют переход, если флаг fpcond имеет значение ЛОЖЬ или ИСТИНА соответственно. Другие варианты сравнений, такие как проверка на неравенство или на то, что один операнд больше другого, или больше или равен другому, осуществляются при помощи команд с суффиксами seq, lt, le и последующей командой bc1f.
- Пример. Использованы инструкции расширенного языка ассемблера.
1 ## newton.asm -- compute sqrt(n)
2
3 ## given an approximation x to sqrt(n),
4 ## an improved approximation is:
5
6 ## x' = (1/2)(x + n/x)
7
8 ## $f0 --- n
9 ## $f1 --- 1.0
10 ## $f2 --- 2.0
11 ## $f3 --- x : current approx.
12 ## $f4 --- x' : next approx.
13 ## $f8 --- temp
14
15 .text
16 .globl main
17
18 main:
19
20 l.s $f0,n # get n
21 l.s $f1,con_1 # constant 1.0
22 l.s $f2,con_2 # constant 2.0
23 l.s $f3,con_1 # x == first approx.
24 l.s $f10,ep # five figure accuracy
25
26 loop:
27 mov.s $f4,$f0 # x' = n
28 div.s $f4,$f4,$f3 # x' = n/x
29 add.s $f4,$f3,$f4 # x' = x + n/x
30 div.s $f3,$f4,$f2 # x = (1/2)(x + n/x)
31
32 mul.s $f8,$f3,$f3 # x^2
33 div.s $f8,$f0,$f8 # n/x^2
34 sub.s $f8,$f8,$f1 # n/x^2 - 1.0
35 abs.s $f8,$f8 # |n/x^2 - 1.0|
36 c.lt.s $f8,$f10 # |x^2 - n| < small ?
37 bc1t done # yes: done
38
39 j loop # next approximation
40
41 done:
42 mov.s $f12,$f3 # print the result
43 li $v0,2
44 syscall
45
46 li $a0,0
47 li $v0,10 # return to OS
48 syscall
49 ##
50 ## Data Segment
51 ##
52 .data
53 n: .float 4.0
54 ep: .float 1.0e-5
55 con_1: .float 1.0
56 con_2: .float 2.0