X87

Origem: Wikipédia, a enciclopédia livre.

x87 - É o nome genérico dado aos co-processadores Intel de ponto flutuante que funcionavam em conjunto com os processadores de dados, cada um com o seu par. Originou-se como uma extensão da instrução set 8086 na forma de co-processadores de ponto flutuante opcional que trabalhou em conjunto com CPUs x86 correspondentes. Estes microchips tinham nomes terminados em "87". Como outras extensões para o conjunto de instruções básicas, as instruções x87 não são estritamente necessárias para a construção de programas de trabalho, mas para fornecer hardware e microcódigo em implementações de tarefas comuns numérica, permitindo que estas tarefas sejam executadas muito mais rapidamente que as rotinas de código normais. O conjunto de instruções x87 inclui instruções para operações básicas de ponto flutuante, como adição, subtração e comparação, mas também para mais complexas operações numéricas, como o cálculo da função tangente e seu inverso.

A maioria dos processadores x86 desde o Intel 80486 tiveram estas instruções x87 implementadas na CPU principal, mas o termo ainda é usado para se referir a essa parte do conjunto de instruções. Antes das instruções x87 serem padrão em PCs, os compiladores ou programadores tinham de usar uma biblioteca bastante lenta para fazer chamadas ou executar operações de ponto flutuante, um método que ainda é comum em (baixo custo) sistemas embarcados.


Descrição[editar | editar código-fonte]

Os registros da x87 formam uma estrutura de nível 8-deep stack não-rígidas que vão desde ST (0) para ST (7) com registros que podem ser acessados diretamente por qualquer operando, usando um deslocamento em relação ao superior como em uma pilha. Há instruções para deslocar e calcular valores no topo desta pilha, operações monádicas (FSQRT, FPTAN etc), no endereço ST superior (0) enquanto as operações diádicas (FADD, FMUL, FCOM, etc) nos ST (0) e ST (1). O modelo de pilha não-estrita também permite a operações diádicas usarem ST (0) juntamente com um operando de memória direto ou com uma especifica pilha-registro, ST (x), em um papel semelhante a um acumulador tradicional (um destino combinado e operando à esquerda).

Isso também pode ser revertido em uma base de instrução por instrução com ST (0) com o operando modificado e ST (x) como destino. Além disso, o conteúdo de ST (0) pode ser trocado com outro registro pilha usando uma instrução chamada FXCH ST (x).

Isso faz com que as pilhas x87 sejam utilizaveis em 7 registradores de endereço mais um acumulador dedicado (ou até sete acumuladores independentes). Isto é especialmente aplicável em superprocessadores escalares x86 (como o Pentium de 1993 e posteriores), onde estas instruções de troca (códigos D9C8 .. D9CFh) são otimizadas para baixo a zero clock, usando um dos caminhos inteiro para FXCH ST (x) em paralelo com a instrução FPU. Apesar de ser natural e conveniente para os programadores da linguagem assembly, alguns desenvolvedores de compiladores tem encontrado dificuldade para construir geradores de código automático que agendem código de forma eficaz.

O x87 fornece precisão simples, dupla precisão e 80-bit de precisão estendida duplamente binária-aritmética de ponto flutuante de acordo com a IEEE 754-1985 padrão. Por padrão, os processadores x87 usam 80-bit de precisão dupla estendida internamente (para permitir a precisão sustentada durante muitos cálculos). Uma determinada seqüência de operações aritméticas podem se comportar de forma ligeiramente diferente em comparação com uma precisão única ou de precisão dupla IEEE 754 FPU [1]. Isso às vezes pode ser problemático para alguns cálculos semi-numéricos confiando no conhecimento de precisão FPU exato para a operação correta. Para evitar tais problemas, o x87 pode ser configurado através de um status especial de configuração que registra automaticamente a volta para precisão simples ou dupla, após cada operação. Desde a introdução do SSE2, as instruções x87 não são tão essenciais quanto eram uma vez, exceto para alta precisão cálculos exigindo a precisão de 64 bits mantissa disponível no formato 80-bit.


Desempenho[editar | editar código-fonte]

Contagem de ciclo de relógio para exemplos de típicos instruções x87 FPU (apenas versões registradas são mostradas).

A notação A ~ B (mínimo ao máximo), abrange variações de tempo dependente do estado da pipeline transitória, bem como a precisão aritmética escolhida (32, 64 ou 80 bits), que também inclui variações devido a casos numéricos (como o número de bits definidos, zeros, etc.) A notação L → H retrata valores correspondentes a mais baixa (L) e o mais alto (H) freqüências de clock máximo que estavam disponíveis. vale a pena ter

x87 implementation FADD FMUL FDIV FXCH FCOM FSQRT FPTAN FPATAN Max Clock Peak FMUL/sec Relative 5 MHz 8087§ FMUL
8087 70~100 90~145 193~203 10~15 40~50 180~186 30~540 250~800 5→10 MHz 34~55K → 100~111K 1.0 → 2.0 times as fast
80287 (original) 70~100 90~145 193~203 10~15 40~50 180~186 30~540 250~800 6→12 MHz 41~66K → 83~133K 1.2 → 2.4 times as fast
80387 (and later 287 models) 23~34 29~57 88~91 18 24 122~129 191~497 314~487 16→33 MHz 280~552K → 579~1100K approx 10 → 20 × as fast
80486 (or 80487) 8~20 16 73 4 4 83~87 200~273 218~303 16→50 MHz 1.0M → 3.1M approx 18 → 56 × as fast
Cyrix 6x86, Cyrix MII 4~7 4~6 24~34 2 4 59~60 117~129 97~161 66→300 MHz 11~16M → 50~75M approx 320 → 1400 ×
AMD K6 (including K6 II/III) 2 2 todo 2 todo todo todo todo 166→550 MHz 83M → 275M approx 1500 → 5000 ×
Pentium / Pentium MMX 1~3 1~3 39 1 (0*) 1~4 70 17~173 19~134 60→300 MHz 20~60M → 100~300M approx 1100 → 5400 ×
Pentium Pro 1~3 2~5 16~56 1 (0*) 1 28~68 todo todo 150→200 MHz 30~75M → 40~100M approx 1400 → 1800 ×
Pentium II / III 1~3 2~5 17~38 1 (0*) 1 27~50 todo todo 233→1400 MHz 47~116M → 280~700M approx 2100 → 13000 ×
Athlon (K7) 1~4 1~4 13~24 1 (0*) 1~2 16~35 todo todo 500→2330 MHz 125~500M → 0.580~2.33G approx 9000 → 42000 ×
Pentium 4 1~5 2~7 20~43 1 (0*) todo 20~43 todo todo 1.3→3.8 GHz 186~650M → 0.543~1.90G approx 11000 → 34000 ×
Athlon 64 (K8) 1~4 1~4 13~24 1 (0*) 1~2 16~35 todo todo 1.0→3.2 GHz 250~1000M → 0.800~3.2G approx 18000 → 58000 ×

* Um atraso de clock efetivo zero é frequentemente possível, via execução superescalar. § 5 MHz 8087 foi o processador x87 original. Comparando softwares implementados com rotinas de ponto flutuante em um 8086 (sem 8087), os fatores seriam ainda maiores, talvez por um outro fator de 10 (ou seja, uma adição ponto correto flutuante em linguagem assembly pode muito bem consumir mais de 1000 ciclos).

Fabricantes[editar | editar código-fonte]

Empresas que tenham desenvolvido ou fabricado unidades de ponto flutuante compatível com o Intel 8087 ou modelos mais recentes incluem: AMD (287, 387 486DX, 5x86, K5, K6, K7, K8), Chips and Technologies (o co-processadores MATH Super), Cyrix (o FasMath, Cx87SLC, Cx87DLC, etc, 6x86, Cyrix MII), Fujitsu (início Pentium Mobile, etc), Harris Semiconductor (fabricado 80387 e processadores 486DX), IBM (387 e 486 desenhos diferentes), IDT (o WinChip, C3, C7, Nano, etc), IIT (o 2C87, 3C87, etc), LC Tecnologia (coprocessors MATH Green), National Semiconductor (o Geode GX1, Geode GXM, etc), NexGen (o Nx587), Tecnologia Rise (o MP6), ST Microelectronics (486DX fabricados, 5x86, etc), Texas Instruments (processadores 486DX fabricados, etc), Transmeta (TM5600 e TM5800 a), ULSI (o Math · coprocessors Co), VIA (o C3 , C7 e Nano, etc) e Xtend (o co-processadores 83S87SX-25 e outros).

Arquiteturas[editar | editar código-fonte]

8087[editar | editar código-fonte]

O 8087 foi o primeiro co-processador matemático para processadores 16-bit projetado pela Intel (o I8231 era mais velho, mas projetado para a Intel 8-bit 8080), que foi construído para ser emparelhado com o Intel 8088 ou 8086 microprocessadores.

Instruções original do 8087[editar | editar código-fonte]

Instrução Significado Notas
F2XM1 2x - 1 maior precisão que 2x para perto de zero
FABS Valor absoluto
FADD Soma
FADDP Soma e "Pop (ver LIFO)"
FBLD Carrega BCD
FBSTP Carrega BCD e "Pop (ver LIFO)"
FCHS Troca sinal
FCLEX Limpa execções
FCOM Compara
FCOMP Compara e "Pop (ver LIFO)"
FCOMPP Compara e "Pop (ver LIFO)" duas vezes
FDECSTP Decrementa o ponteiro da pilha de ponto flutuante
FDISI Desativa Interrupções
FDIV Divide
FDIVP Divide e "Pop (ver LIFO)"
FDIVR Divide reservado
FDIVRP Divide reservado e "Pop (ver LIFO)"
FENI Ativa interrupções
FFREE Libera registrador
FIADD Soma de inteiros
FICOM Comparação de inteiros
FICOMP Comparação de inteiros e "Pop (ver LIFO)"
FIDIV Divide inteiros
FIDIVR Divide inteiros reversamente
FILD Carrega inteiros
FIMUL Multiplicação de inteiros
FINCSTP Incrementa o ponteiro da pilha de ponto flutuante
FINIT Inicializa processador de ponto flutuante
FIST Armazena inteiro
FISTP Armazena inteiro e "Pop (ver LIFO)"
FISUB Subtração de inteiros
FISUBR Subtração de inteiros reversamente
FLD Carrega ponto flutuante
FLD1 Carrega 1.0 na pilha
FLDCW Carrega palavra de controle
FLDENV Carrega estado de ambiente
FLDL2E Carrega log2(e) na pilha
FLDL2T Carrega log2(10) na pilha
FLDLG2 Carrega log10(2) na pilha
FLDLN2 Carrega ln(2) na pilha
FLDPI Carrega π na pilha
FLDZ Carrega 0.0 na pilha
FMUL Multiplica
FMULP Multiplica e "Pop (ver LIFO)"
FNCLEX Limpa execções, nenhuma espera
FNDISI Desativa execções, nenhuma espera
FNENI Ativa execções, nenhuma espera
FNINIT Inicializa processador de ponto flutuante, nenhuma espera
FNOP Nenhuma operação
FNSAVE Salva o estado da FPU, nenhuma espera, 8-bit
FNSAVEW Salva o estado da FPU, nenhuma espera, 16-bit
FNSTCW Armazena palavra de controle, nenhuma espera
FNSTENV Armazena o ambiente da FPU, nenhuma espera
FNSTENVW Armazena o ambiente da FPU, nenhuma espera, 16-bit
FNSTSW Armazena palavra de status, nenhuma espera
FPATAN Arcotangente parcial
FPREM Resto parcial
FPTAN Tangente parcial
FRNDINT Arredonda para inteiro
FRSTOR Restaura estado salvo
FSAVE Salva o estado da FPU
FSAVEW Salva o estado da FPU, 16-bit
FSCALE Escala por fator de 2
FSQRT Raiz quadrada
FST Armazena ponto flutuante
FSTCW Armazena palavra de controle
FSTENV Armazena ambiente da FPU
FSTENVW Armazena ambiente da FPU, 16-bit
FSTP Armazena e "Pop (ver LIFO)"
FSTSW Armazena palavra de estado
FSUB Subtração
FSUBP Subtração e "Pop (ver LIFO)"
FSUBR Subtrai reversamente
FSUBRP Subtrai reversamente e "Pop (ver LIFO)"
FTST Testa por ZERO
FWAIT Aguarda enquanto a FPU está executando
FXAM Examina flags de condição
FXCH Troca registradores
FXTRACT Extrai expoente e significado
FYL2X y * log2(x) se , então a base- logaritmica é computada
FYL2XP1 y * log2(x+1) mais precisão que se está perto de ZERO


80287[editar | editar código-fonte]

Versão 6 MHz da Intel 80287 Intel 80287XL. Intel 80287XLT.

80287(i287)[editar | editar código-fonte]

O 80287 (i287) foi o co-processador matemático para o 80286 Intel série de microprocessadores. Intel (e seus concorrentes) mais tarde introduziu um 80287XL, que era na verdade um 80387SX com uma pinagem 287. O 80287XL continha um multiplicador de 3 / 2 interna, de modo que as placas mãe que corria o co-processador de 2 / 3 da velocidade da CPU pode executar o FPU vez na mesma velocidade da CPU. Outros modelos com 287 387-como o desempenho foram o Intel 80C287, construído usando CHMOS III, eo AMD 80EC287 fabricado em processo da AMD CMOS, usando apenas portas totalmente estática.

80287XL e 80287XLT[editar | editar código-fonte]

O 80287 e 80287XL também trabalhou com o microprocessador 80386, e foram, inicialmente, o co-processadores só está disponível para o 80386 até a introdução dos 80.387 em 1987. Finalmente, eles também foram capazes de trabalhar com o Cx486SLC Cyrix. No entanto, para ambos os chips da 80387 foi o preferido para o seu maior desempenho e maior capacidade de seu conjunto de instruções.Modelos da Intel incluíram i80287 variantes com limites de frequência superior que variam de 6 até 12 MHz. Mais tarde seguiu a i80287XL com 387 micro-arquitetura, o i80287XLT, uma versão especial destinado a laptops, bem como outras variantes.

80387[editar | editar código-fonte]

O 80387 (387 ou i387) foi o co-processador Intel primeira a ser totalmente compatível com o padrão IEEE 754. Lançado em 1987, um total de dois anos após o chip 386, o i387 incluída velocidade muito melhorado ao longo anteriores da Intel 8087/80287 co-processadores, e melhorou as características das funções trigonométricas. (A faixa de 80.287 a limitada argumento para mais ou para menos 45 graus.)

Sem um co-processador, o 386 normalmente desempenhadas aritmética de ponto flutuante através de rotinas (lento) software, implementado em tempo de execução através de um software manipulador de exceção. Quando um co-processador matemático está emparelhado com o 386, o co-processador executa a aritmética de ponto flutuante em hardware, retornando resultados muito mais rápido do que uma chamada de biblioteca.

O i387 é compatível apenas com o chip padrão i386, que tinha um barramento do processador de 32 bits. O i386SX depois teve custo reduzido, teve um estreito de 16 bits de barramento de dados, não poderia interagir com o bus i387 de 32 bits. O i386SX necessários a sua própria co-processador, o Intel 80387SX, que era compatível com o estreito de SX em barramento de dados 16-bit.

80187[editar | editar código-fonte]

O 80187 (80C187) foi o co-processador matemático para Intel 80186 e 80188 CPUs. O 80187 não apareceu ao mesmo tempo, como o 80186 e 80188, mas na verdade foi lançado após o 80287 eo 80387. Embora a interface para o processador principal foi o mesmo que o 8087, seu núcleo foi a dos 80.387, e foi, assim, plenamente compatível com IEEE 754, bem como capaz de executar todas as instruções de 80.387 extra. Embora a 8087 era perfeitamente capaz de operar com um 80186 ou 80188, o 80187 não funciona particularmente bem com o 8086 ou 8088. Há diferenças suficientes que o código tem que ser escrito especialmente para permitir uma combinação 80187 e 8086 / 8 a funcionar perfeitamente.

80487[editar | editar código-fonte]

O i487SX foi comercializado como um co-processador de ponto flutuante de unidade para Intel i486SX máquinas. Ele realmente continha uma implementação i486DX full-blown. Quando instalado em um sistema i486SX, o i487 desativava o CPU principal e assumia todas as operações da CPU. O i487 tomou medidas para detectar a presença de um i486SX e não funcionar sem a CPU original no lugar.

80587[editar | editar código-fonte]

O Nx587 foi o FPU x86 durar a ser fabricado separadamente da CPU, neste caso Nx586 NexGen.