This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:multiasm:papc:chapter_6_10 [2025/10/31 08:23] – [Basic arithmetic instructions] ktokarz | en:multiasm:papc:chapter_6_10 [2025/10/31 16:28] (current) – [Table] ktokarz | ||
|---|---|---|---|
| Line 18: | Line 18: | ||
| </ | </ | ||
| + | The stack organisation of registers makes it easier to implement math calculations according to the RPN (Reverse Polish Notation), also called postfix notation. | ||
| Further in this section, we'll present the FPU coprocessor' | Further in this section, we'll present the FPU coprocessor' | ||
| * data transfer instructions, | * data transfer instructions, | ||
| Line 155: | Line 156: | ||
| The basic arithmetic instructions also contain instructions for other calculations. The **fprem** and **fprem1** calculate the partial remainder obtained from dividing the value in the ST(0) register by the value in the ST(1) register. The **fabs** calculate the absolute value of ST(0). The **fchs** changes the sign of ST(0). The **frndint** rounds the ST(0) to an integer. The **fscale** scales ST(0) by a power of two taken from ST(1), while **fxtract** separates the value in ST(0) into the exponent placed in ST(0) and the significand, | The basic arithmetic instructions also contain instructions for other calculations. The **fprem** and **fprem1** calculate the partial remainder obtained from dividing the value in the ST(0) register by the value in the ST(1) register. The **fabs** calculate the absolute value of ST(0). The **fchs** changes the sign of ST(0). The **frndint** rounds the ST(0) to an integer. The **fscale** scales ST(0) by a power of two taken from ST(1), while **fxtract** separates the value in ST(0) into the exponent placed in ST(0) and the significand, | ||
| + | ===== Comparison instructions ===== | ||
| + | The comparison instructions compare two floating point values and set flags appropriate to the result. The operand of the **fcom** instruction can be a memory operand or another FPU register. It is always compared with the top of the stack. If no operand is specified, it compares ST(0) and ST(1). Popped version **fcomp** pops ST(0) off the stack. The instruction **fcompp** with double " | ||
| + | If one of the arguments is NaN, they generate the invalid arithmetic operand exception. To avoid unwanted exceptions, there are unordered versions of comparison instructions. These are **fucom**, **fucomp**, and **fucompp**. Unordered comparison instructions do not operate with memory arguments. Two instructions are implemented to compare integers. The **ficom** and **ficomp** have a single memory argument that can be a word or doubleword, which is compared with the top of the stack. | ||
| + | Original instructions set flags C0, C2 and C3 in the FPU status word register. After implementing FPU as the integral unit of the processor, a new set of instructions appeared that set flags in the FLAGS register directly. There are **fcomi**, **fcomip**, **fucomi** and **fucomip**. Their first argument is always ST(0), the second is another FPU register. | ||
| + | To the group of the comparison instructions also belong **fxam** and **ftst** instructions. The **fxam** instruction classifies the value of ST(0), while the **ftst** instruction compares ST(0) with the value of 0.0. They return the information in C0, C2 and C3 flags. | ||
| + | ===== Transcendental instructions ===== | ||
| + | The transcendental instructions perform calculations of advanced mathematical functions. | ||
| + | The **fsin** instruction calculates the sine, while the **fcos** calculates the cosine of the argument stored in ST(0). The **fsincos** calculates both sine and cosine with the same instruction. The sine is returned in ST(1), the cosine in ST(0). The **fptan** instruction calculates the partial tangent and **fpatan** the partial arctangent. After calculating the tangent, the value of 1.0 is pushed onto the stack to make it easier to calculate cotangent afterwards by execution **fdivr** instruction. The partial means that this instruction handles only a limited range of input arguments. | ||
| + | The instructions for exponential and logarithmic functions are summarised in table {{ref> | ||
| + | <table ftrans> | ||
| + | < | ||
| + | ^ Mnemonic | ||
| + | | **f2xm1** | ||
| + | | **fyl2x** | ||
| + | | **fyl2xp1** | ||
| + | </ | ||
| + | ===== FPU control instructions ===== | ||
| + | The FPU control instructions help the programmer to save and restore the contents of chosen registers if there is a need to use them in an interrupt handler or inside a function. It is also possible to initialise the state of the FPU unit or clear errors. | ||
| + | The **fincstp** increments and **fdecstp** decrements the FPU register stack pointer. | ||
| + | The following set of instructions can perform error checking while execution (instructions without " | ||
| + | The **finit** and **fninit** initialise the FPU (after checking error conditions or without checking error conditions). | ||
| + | The **fclex** and **fnclex** clear floating-point exception flags. | ||
| + | The **fstcw** and **fnstcw** store the FPU control word. | ||
| + | The **fldcw** loads the FPU control word. | ||
| + | The **fstenv** and **fnstenr** store the FPU environment. The environment consists of the FPU control word, status | ||
| + | word, tag word, instruction pointer, data pointer, and last opcode register. | ||
| + | The **fldenv** loads the FPU environment. | ||
| + | The **fsave** and **fnsave** save the FPU state. The state is the operating environment and full register stack. | ||
| + | The **frstor** restores the FPU state. | ||
| + | The **fstsw** and **fnstsw** store the FPU status word. There is no instruction for restoring the status word. | ||
| + | The **wait** or **fwait** waits for the FPU to finish the operation. | ||
| + | The **fnop** instruction is the no operation instruction for the FPU. | ||