12
CS220 April 18, 2007

Floating Point Instructions

Embed Size (px)

DESCRIPTION

Professional Assembly Language

Citation preview

Page 1: Floating Point Instructions

CS220

April 18, 2007

Page 2: Floating Point Instructions

Floating Point Instructions• filds/fildl Loads 32 bits integer into FPU• fists/fistl Stores top reg value to 32 bits memory• fbld Loads BCD• fbst Stores BCD• fadd Floating-point addition• fdiv Floating-point division• fdivr Reverse floating-point division• fmul Floating-point multiplication• fsub Floating-point subtraction• fsubr Reverse floating-point subtraction• frndint Rounds the value in st(0) to the nearest int• fsqrt Computes the square root of the value in st(0)• fxch Exchange registers

Note: FP instructions can’t use immediate number as operand, and can’t use one FP reg and one memory variable. You need to worry about s/l surffix only when dealing with memory. i.e. fadds -4(%ebp) but fadd %st(1), %st(2)

Page 3: Floating Point Instructions

Examples• fadds data1

– add the 32-bit value at data1 to the st(0) register• fmull data1

– multiply the 64-bit value at data1 with the st0 register• fidiv data1

– divide st(0) by the 32-bit integer value at data1, and store in st(0)• fsub %st(0), %st(1)

– st(1)= st(0) - st(1)• fsubr %st(0), %st(1)

– st(1)= st(1) - st(0)• fdivs data1

– devide the value st(0) by data1, and store in st(0)• faddp

– Add st(0) to st(1), store the result in st(1), and pop st(0)• flds var1

flds var2fdivp

– var2 at st(0) is divided by var1 at st(1), store in st(1) then pop, result now in st(0)

No operand:st(0) and st(1)

One operand:st(0) omitted

Compare: subl %eax, %ebx%ebx=%ebx-%eax

Page 4: Floating Point Instructions

pop after operations

• fstp• fistp• faddp• fsubp• fmulp• fdivp• …

After pop:

st(1) ->st(0)

st(2)->st(1)

st(0)->st(7) (invalid value, can’t be used)

Page 5: Floating Point Instructions

fld1fldzflds var1fldpi

faddp

fadds var2

fadd %st(0), %st(2)

st0 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)st1 1.10000002384185791015625 (raw 0x3fff8ccccd0000000000)st2 0 (raw 0x00000000000000000000)st3 1 (raw 0x3fff8000000000000000)st4 0 (raw 0x00000000000000000000)st5 0 (raw 0x00000000000000000000)st6 0 (raw 0x00000000000000000000)st7 0 (raw 0x00000000000000000000)

st0 4.2415926774316511484522185249090853 (raw 0x400187bb209110b4611a)st1 0 (raw 0x00000000000000000000)st2 1 (raw 0x3fff8000000000000000)st3 0 (raw 0x00000000000000000000)st4 0 (raw 0x00000000000000000000)st5 0 (raw 0x00000000000000000000)st6 0 (raw 0x00000000000000000000)st7 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)

st0 6.4415927251153669687647185249090853 (raw 0x4001ce21871110b4611a)st1 0 (raw 0x00000000000000000000)st2 1 (raw 0x3fff8000000000000000)st3 0 (raw 0x00000000000000000000)st4 0 (raw 0x00000000000000000000)st5 0 (raw 0x00000000000000000000)st6 0 (raw 0x00000000000000000000)st7 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)

st0 6.4415927251153669687647185249090853 (raw 0x4001ce21871110b4611a)st1 0 (raw 0x00000000000000000000)st2 7.4415927251153669687647185249090853 (raw 0x4001ee21871110b4611a)st3 0 (raw 0x00000000000000000000)st4 0 (raw 0x00000000000000000000)st5 0 (raw 0x00000000000000000000)st6 0 (raw 0x00000000000000000000)st7 3.1415926535897932385128089594061862 (raw 0x4000c90fdaa22168c235)

(var1=1.1, var2=2.2)

invalid

Page 6: Floating Point Instructions

float add(float a,float b){

return a+b;}

.text.globl add

.type add, @functionadd:

pushl %ebpmovl %esp, %ebpflds 8(%ebp)fadds 12(%ebp)leaveret.size add, .-add

void main(){

float f1=1.1f,f2=2.2f;printf("f1 + f2 = %f\n",add(f1,f2));

}

.section .rodata.LC3:

.string "f1 + f2 = %f\n"

.text.globl main

.type main, @functionmain:

pushl %ebpmovl %esp, %ebpsubl $8, %espmovl $0x3f8ccccd, %eaxmovl %eax, -4(%ebp)movl $0x400ccccd, %eaxmovl %eax, -8(%ebp)pushl -8(%ebp)pushl -4(%ebp)call addaddl $8, %espsubl $8, %esp # leal -8(%esp), %espfstpl (%esp)pushl $.LC3call printfaddl $12, %espleaveret.size main, .-main

Page 7: Floating Point Instructions

double mul(double a,double b){

return a*b;}

.text.globl mul

.type mul, @functionmul:

pushl %ebpmovl %esp, %ebpfldl 8(%ebp) fmull 16(%ebp)leaveret.size mul, .-mul

void main(){

double d1=1.1, d2=2.2;printf("d1 + d2 = %f\n",mul(d1,d2));

}

.section .rodata.LC3:

.string "f1 + f2 = %f\n" .text.globl main

.type main, @functionmain:

pushl %ebpmovl %esp, %ebpsubl $16, %espmovl $1072798105, %edxmovl $-1717986918, %eaxmovl %edx, -4(%ebp)movl %eax, -8(%ebp)movl $1073846681, %edxmovl $-1717986918, %eaxmovl %edx, -12(%ebp)movl %eax, -16(%ebp)pushl -12(%ebp)pushl -16(%ebp)pushl -4(%ebp)pushl -8(%ebp)call muladdl $16, %espsubl $8, %esp # leal -8(%esp), %espfstpl (%esp)pushl $.LC3call printfaddl $12, %espleaveret

#a: 8(%ebp) and 12(%ebp)

#b: 16(%ebp) and 20(%ebp)

#d1’s low part#d1’s high part

#d1’s high part#d1’s low part

Little Endian:

Use lower 32-bit address to access a 64 bits number

Little Endian:

High part high address

Low part low address

Page 8: Floating Point Instructions

Rounding Example• Control reg 10–11 Rounding control

00 - round to nearest (default)01 - round down (toward negative

infinity)10 - round up (toward positive infinity)11 - round toward zero

pushfpush %eax

finitflds value1frndintfists resultnearest

fstcw tmpmovw tmp, %axandw $0b1111001111111111, %axorw $0b0000010000000000, %axmovw %ax, tmpfldcw tmpflds value1frndintfists resultdown

popl %eaxpopfleaveret.size main, .-main

.section .datavalue1:

.float 3.65.section .bss

.lcomm resultnearest, 4

.lcomm resultdown, 4

.lcomm tmp, 2.text.globl main

.type main, @functionmain:

pushl %ebpmovl %esp, %ebp

4

3

Page 9: Floating Point Instructions

Reverse Polish Notation (RPN)• Infix notation: x * y• RPN: x y *

• Example:x = ((y-z)*a) - ( a + b * c )/3.14159

x = ([y z -] * a) - ( a + b * c )/3.14159x = [y z - a *] - ( a + b * c )/3.14159x = [y z - a *] - ( a + [b c *])/3.14159x = [y z - a *] - [a b c * +]/3.14159x = [y z - a *] - [a b c * + 3.14159 /]x = [y z - a *] [a b c * + 3.14159 /] -x = y z - a * a b c * + 3.14159 / -

Page 10: Floating Point Instructions

((43.65 / 22) + (76.34 * 3.1)) / ((12.43 * 6) – (140.2 / 94.21))

1. Load 43.65 into st(0).2. Divide st(0) by 22, saving the results in st(0).3. Load 76.34 in st(0) (the answer from step 2 moves to st(1)).4. Load 3.1 in st(0) (the value in step 3 moves to st(1), and the answer from Step 2 moves

to st(2)).5. Multiply st(0) and st(1), leaving the answer in st(0).6. Add st(0) and st(2), leaving the answer in st(0) (this is the left side of the equation).7. Load 12.43 into st(0) (the answer from Step 6 moves to st(1)).8. Multiply st(0) by 6, leaving the answer in st(0).9. Load 140.2 into st(0) (the answer from Step 8 moves to st(1), and from Step 6 to st(2)).10. Load 94.21 into st(0) (the answer from Step 8 moves to st(2), and from Step 6 to ST3).11. Divide st(1) by st(0), popping the stack and saving the results in st(0) (the answer from

Step 812. moves to st(1), and from Step 6 to st(2)).13. Subtract st(0) from st(1), storing the result in st(0) (this is the right side of the equation).14. Divide st(2) by st(0), storing the result in st(0) (this is the final answer).

This example comes from recommended textbook; it doesn’t really follow RPN notation

Page 11: Floating Point Instructions

((43.65 / 22) + (76.34 * 3.1)) / ((12.43 * 6) – (140.2 / 94.21))

Page 12: Floating Point Instructions

.section .datavalue1:

.float 43.65value2:

.int 22value3:

.float 76.34value4:

.float 3.1value5:

.float 12.43value6:

.int 6value7:

.float 140.2value8:

.float 94.21output:

.string "The result is %f\n"

.text.globl main

.type main, @functionmain:

pushl %ebpmovl %esp, %ebp

finitflds value1fidiv value2flds value3flds value4fmul %st(1), %st(0)fadd %st(2), %st(0)flds value5fimul value6flds value7flds value8fdivrpfsubr %st(1), %st(0)fdivr %st(2), %st(0)subl $8, %espfstpl (%esp)pushl $outputcall printfadd $12, %esp

leaveret.size main, .-main

((43.65 / 22) + (76.34 * 3.1)) /

((12.43 * 6) – (140.2 / 94.21))