اینتل ۸۰۸۷

طراحی و توسعه

اینتل قبل از این، واحد پردازنده محاسباتی ۸۲۳۱ و پردازنده عدد اعشاری ۸۲۳۲ تولید کرده بود. این‌ها برای استفاده با ۸۰۸۰ یا پردازنده‌های مشابه طراحی شده بود و به عنوان یک bus داده‌ای ۸ بیتی استفاده می‌شد. آن‌ها به یک سیستم میزبان از طریق یک سیستم I/O برنامه‌ریزی شده یا یک کنترل‌کننده DMA متصل می‌شدند.
۸۰۸۷ در ابتدا توسط بیل پولمن، مدیر مهندسی اینتل که به توسعه تراشه ۸۰۸۶ نظارت داشت، درک شد. بیل اقدام‌های لازم را برای اطمینان از اینکه تراشه ۸۰۸۶ می‌تواند از یک تراشه ریاضی هنوز در حال توسعه پشتیبانی کند، انجام داد.
ولمن در سال ۱۹۷۷ برای طراحی تراشه ریاضی ۸۰۸۷ اقدام کرد. بروس راونال به عنوان معمار منسوب شد و جان پالمر به عنوان کمک-معمار و ریاضیدان برای این پروژه استخدام شد. این دو با یک طراحی انقلابی با ۶۴ بیت mantissa و ۱۶ بیت نما برای طولانی‌ترین فرمت عدد حقیقی، با پردازندهٔ معماری پشته‌ای و ۸ ثبات پشته ۸۰ بیتی، با مجموعه ای از دستورالعمل‌های محاسباتی غنی آمدند. این طراحی چند مشکل عمده شناخته شده در محاسبات عددی و نرم‌افزار عددی را حل کرد: ایرادات خطای گرد کردن برای عملوندهای ۶۴ بیتی حذف شدند و تبدیل‌های عددی برای تمام اعداد ۶۴ بیتی حل شد. پالمر نوشته‌های ویلیام کاهان در مورد عدد اعشاری را عامل مؤثر قابل توجهی در طراحی‌شان نسبت داد.
طراحی ۸۰۸۷ در آغاز به دلیل طراحی جنجالی آن، در سانتا کلارا پذیرفته شد. در نهایت، این طراحی به اینتل اسرائیل نسبت داده شد، و رفی نوا یه عنوان راهنما پیاده‌سازی این تراشه انتخاب شد.
به پالمر، راونال و نوا حق امتیاز برای این طراحی اهدا شد. رابرت کوهلر و جان بیلیس نیز حق ثبت اختراع برای این تکنیک اعطا شد که در آن برخی از دستورالعمل‌ها با الگوی بیتی خاصی به کمک-پردازنده تخلیه شده بود.
۸۰۸۷ دارای ۴۵٬۰۰۰ ترانزیستور بود و به عنوان یک تخلیه بار ۳ میکرومتر مدار HMOS ساخته شده بود. آن در کنار ۸۰۸۶ یا ۸۰۸۸ کار کرد و حدود ۶۰ دستورالعمل جدید معرفی کرد. بیشتر ۸۰۸۷mnemonicهای اسمبلی با حرف F شروع می‌شوند مانند FADD FMUL , FCOM و … که باعث می‌شود از دستورالعمل‌های ۸۰۸۶ به راحتی قابل تشخیص باشند. رمزگذاری دودویی برای تمام دستورالعمل‌های ۸۰۸۷ با الگوی ۱۱۰۱۱های اعشاری، ۲۷ در مبنای ده، همان کاراکتر اسکی ESC اگر چه در مرتبه بالاتر بیت از یک بایت؛ پیشوندهای دستورالعمل‌های مشابه نیز گاهی اوقات به عنوان
"کدهای فرار" معرفی می‌شوند. دستور حفظی اختصاص داده شده توسط اینتل برای این کمک-پردازنده‌ها دستورالعمل "ESC" است.
زمانی که پردازنده ۸۰۸۶ یا ۸۰۸۸ دستور ESC را اجرا می‌کرد، اگر بایت دوم (بایت ModR/M) یک عملوند حافظه را مشخص می‌کرد، پردازنده برای خواندن یک کلمه از حافظه مشخص شده در دستورالعمل (با استفاده از هر مد آدرس‌دهی) یک چرخه bus اجرا می‌کرد، ولی عملوند خوانده شده را در ثبات‌های CPU ذخیره نمی‌کرد یا عملیاتی روی آن انجام نمی‌داد؛ 8087 bus را مشاهده و دستورالعمل‌های جریان همگام با ۸۰۸۶ را رمزگشایی می‌کرد، تشخیص دستورالعمل‌های کمک-پردازنده برای خودش ارزشمند بود. برای یک ۸۰۸۷ دستورالعمل با عملوند حافظه، اگر دستورالعمل فراخوانی شده برای عملوندی که خوانده شود، ۸۰۸۷ کلمهٔ داده خوانده شده توسط پردازنده اصلی را از اتوبوس داده می‌گیرد. اگر عملوند مقرر به خوانده شدن بلندتر از یک کلمه بود، ۸۰۸۷ نیز آدرس را از اتوبوس آدرس کپی خواهد کرد؛ سپس بعد از اتمام خواندن داده‌های چرخه رانده شده توسط پردازنده، ۸۰۸۷ بلافاصله با استفاده از DMA کنترل اتوبوس را گرفته و بایت‌های عملوند اضافی را خودش منتقل می‌کند. اگر یک دستورالعمل۸۰۸۷ با یک عملوند حافظه برای آن عملوندی که باید نوشته شود فراخوانی شود، ۸۰۸۷ کلمه خوانده شده از اتوبوس داده را در نظر نمی‌گیرد و فقط آدرس را کپی می‌کند، سپس از DMA درخواست می‌کند و کل عملوند را می‌نویسد، به همان طریقی که از انتهای یک عملوند گسترده شده می‌خواند. در این راه، پردازنده اصلی کنترل کلی اتوبوس و زمان‌بندی اتوبوس را در حالی که ۸۰۸۷ باقی زمینه‌های اجرای دستورالعمل‌های کمک-پردازنده را مدیریت می‌کند، حفظ می‌کند، بجز دوره‌های زمانی کوتاه DMA، زمانی که ۸۰۸۷ کنترل اتوبوس را برای خواندن یا نوشتن از یا در ثبات‌های خود در دست می‌گیرد. به عنوان یک نتیجه از این طرح، ۸۰۸۷ تنها بر روی عملوندهایی که از حافظه یا از ثبات‌های خودش گرفته بود می‌توانست عمل کند، و هر تبادل اطلاعات بین ۸۰۸۷ و ۸۰۸۶ تنها از طریق RAM امکان‌پذیر بود.
برنامه اصلی پردازنده (CPU) در حالی که ۸۰۸۷ یک دستورالعمل را اجرا کرده‌است، به اجرا ادامه می‌دهد؛ از منظر ۸۰۸۶ اصلی یا پردازنده ۸۰۸۸، یک دستورالعمل کمک-پردازنده به مدت پردازش opcode و هر چرخه عملوند حافظه (۲ چرخه ساعت برای بی‌عملوند، ۸ چرخه ساعت به علاوهٔ زمان محاسبه EA [پنج تا ۱۲ چرخه ساعت]، برای یک عملوند حافظه [به علاوهٔ ۴ چرخه ساعت بیشتر بر روی یک ۸۰۸۸]، برای انتقال دومین بایت از کلمه ،۸ بایت، عملوند)
زمان می‌گیرد، پس از آن که CPU دستورالعمل بعدی برنامه را اجرا کند.
بنابراین، یک سیستم با یک ۸۰۸۷ به‌طور واقع توانایی پردازش موازی را داشت، اجرا کردن یک عملیات داخل ALU عدد صحیحِ پردازنده اصلی در حالی که در همان زمان یک عملیات عدد صحیح در کمک-پردازنده ۸۰۸۷ اجرا می‌شود.
از آنجایی که ۸۰۸۶ یا ۸۰۸۸ منحصراً جریان دستورالعمل‌ها وزمان‌بندی را کنترل می‌کردند و هیچ دسترسی مستقیمی به وضعیت داخلی ۸۰۸۷ ندارد، و به دلیل اینکه ۸۰۸۷ می‌توانست یک دستور بر واحد زمان اجرا کند، برنامه‌های سیستم‌های ۸۰۸۶/۸۰۸۷ یا ۸۰۸۸/۸۰۸۷ باید مطمئن می‌شدند که ۸۰۸۷ زمان کافی برای کامل اجرا کردن دستورالعمل قبلی مواجه شده را داشته باشد قبل از اینکه با دستور دیگری مواجه شود. دستورالعمل WAIT (برای پردازنده اصلی) برای این هدف درست شده بود، و اکثر اسمبلرها به‌طور ضمنی قبل از بیشتر دستورات عدد اعشاری کمک-پردازنده‌ها دستور WAIT را قرار می‌دهند. (در صورتی که برنامه از طرق دیگر اطمینان حاصل کند که زمان کافی بین اجرای دستورات ۸۰۸۷ حساس به زمان وجود دارد تا ۸۰۸۷ دستورالعمل دیگری قبل از اینکه دستور قبلی تمام شود دریافت نکند، دیگر لازم نیست قبل از اجرای یک دستور ۸۰۸۷ از دستور WAIT استفاده کرد. همچنین لزوماً به این شکل نیست که اگر WAIT به کار برده شد، بالافاصله به دستور ۸۰۸۷ بعدی برود) دستور WAIT منتظر پین ورودی -TEST 8086/8088 برای اعلام کردن می‌ماند، و این پین به پین BUSY 8087 داخل تمام سیستم‌هایی که یک ۸۰۸۷ داشتند، متصل شده بود. (پس زمانی TEST اعلام می‌شود که BUSY از حالت اعلام شدن خارج شود).
به دلیل دستورالعمل پیش-فتچ شده صف‌های ۸۰۸۶ و ۸۰۸۸ زمان مورد نیاز برای اجرای یک دستور تا اجرا شود همیشه با زمان لازم برای فتچ کردن یکسان نیست، یک کمک-پردازنده مثل ۸۰۸۷ نمی‌تواند به‌تنهایی با دیدن bus تشخیص دهد که چه زمانی به دستورالعمل بعدی اجرا می‌شود. ۸۰۸۶ و ۸۰۸۸ دارای دو صف سیگنال‌های وضعیت هستند که به کمک-پردازنده متصلند تا به آن امکان همگام‌سازی خود با زمان‌بندی داخلی CPU برای اجرای دستورالعمل‌ها از صف از پیش فتچ شده داشته باشد. ۸۰۸۷ صف از پیش فتچ شدهٔ خود را حفط می‌کند، از جایی که آپکدهای کمک-پردازنده را می‌خواند و اجرا می‌کند. به‌دلیل اینکه صف‌های از پیش فتچ شده سایزهای متفاوت و الگوریتم‌های متفاوت مدیریتی دارند، ۸۰۸۷ با مشاهده خاط‌های معین bus پردازنده زمانی که سیستم ریسِت می‌شود، مشخص می‌کند که به چه نوع پردازنده‌ای متصل شده‌است و بر این اساس صف دستورالعمل داخلی خود را تنظیم می‌کند. کپی کردن زائد صف پیش-فتچ شده سخت‌افزار در CPU و کمک-پردازنده از جهت مصرف توان و از بین بردن فضای کلی ناکار آمد است، ولی باعث شد که رابط کمک-پردازنده به تعداد خیلی کمی پین‌های IC اختصاص پیدا کند، که این مهم بود. در آن زمان که ۸۰۸۶، که رابط کمک-پردازنده را تعریف می‌کرد، معرفی شد ،ICهایی با بیش از ۴۰ پین کمیاب، گران بودند و مشکلاتی از قبیل ظرفیت اضافی lead ،که یک دلیل اصلی در محدود کردن سرعت سیگنال کردن بود، داشت.
کدهای عملیاتی کمک-پردازنده‌ها به کدهایی از ۶ بیت تا ۲ بایت، شروع شده با توالی فرار رمزنگاری می‌شوند.
┐───────────┬───────────┌
│ 1xxx ۱۱۰۱ │ mmxx xrrr │
┘───────────┴───────────└
سه Xs اول، سه بیت اول آپکد عدد اعشاری هستند. سپس دوتا Ms، بعد از آن سه بیت آپکد عدد اعشاری نیمه دوم، دنبالش سه تا Rs هستند. Ms و Rs اطلاعات مد آدرس‌دهی را مشخص می‌کند.
ببرنامه‌های کاربردی باید نوشته می‌شدند تا از دستورالعمل خاص عدد اعشاری استفاده کنند. دز زمان اجرا، نرم‌افزار قادر بود تا کمک-پردازنده را برای عملیات‌های عدد اعشاری پیدا کند. زمانی که نمی‌توانست پیدا کند، برای سازگاری عددی دقیق همان توابع عدد اعشاری می‌بایست داخل نرم‌افزار محاسبه شود یا تمام کمک-پردازنده در نرم‌افزار شبیه‌سازی شود.

ثبات‌ها

خانوادهٔ x87 از سری ثبات‌های قابل آدرس‌دهی مانند ثبات‌های اصلی پردازنده‌های x86 به‌طور مستقیم استفاده نمی‌کنند؛ جای آن، ثبات‌های x87 یک ساختار پشتهای با ۸ سطح عمق که از st0 تا st7 سطح‌بندی می‌شوند، تشکیل می‌دهند. st0 بر روی پشته قرار دارد. عملیات‌های دستورالعمل‌های x87 با push کردن، محاسبه، و pop کردن مقادیر روی این پشته اجرا می‌شوند. اگرچه عملیات‌های دوتایی مثل FADD , FMUL ,FCMP و غیره ممکن است ضمناً از st0 و st1 یا st0 با یک حافظه یا یک ثبات به‌طور غیر ضمنی استفاده کند؛ ثبات st0 می‌تواند به عنوان جمع‌کننده () استفاده شود و همچنین می‌تواند با هر یک از ۸ ثبات پشته از طریق فراخوانی دستورالعمل FXCH stX (کدهای D9C8..D9CFh) جابه‌جا شود. این موجب می‌شود که پشته x87 قابل استفاده به عنوان ۷ ثبات آزاد قابل آدرس‌دهی به علاوه یک جمع‌کننده شود. این مخصوصاً کارآمد بر روی پردازنده‌های x86 superescalar (پنتیوم ۱۹۹۳ و بعد از آن) است جایی که دستورالعمل تعویض به خطای صفر کلاک بهینه‌سازی شده‌اند.

بی‌نهایت

۸۰۸۷ مقادیر بی‌نهایت را به صورت روش وابسته یا طرحی مدیریت می‌کند (از طریق وضعیت ثبات انتخاب می‌شود). در روش وابسته، با بی‌نهایت‌های مثبت و منفی به صورت دو مقدار متفاوت رفتار می‌شود. در روش طرحی، به عنوان نمایش بی علامتی برای اعداد بسیار کوچک یا بسیار بزرگ به کار برده می‌شود. این دو روش برخورد با بی‌تهایتدر نسخه پیش‌نویس استاندارد IEEE 754 گنجانده شده‌است. اگرچه، روش طرحی از نسخه رسمی IEEE 754 در سال ۱۹۸۵ برداشته شد. ۸۰۲۸۷ روش طرحی را به عنوان یک انتخاب حفظ کرد، اما ۸۰۳۸۷ و کمک-پردازنده‌های بعد از آن (شامل ۸۰۱۸۷) فقط روش وابسته را پشتیبانی می‌کردند.

واسط کمک-پردازنده

۸۰۸۷ با کمک-پردازنده‌های بعدی متفاوت بود و آن اتصال مستقیم به busهای داده و آدرس بود. ۸۰۸۷ دنبال دستورالعمل‌هایی که با توالی "۱۱۰۱۱" آغاز می‌شد می‌گشت و با آن‌ها رفتار به خصوصی انجام می‌داد، به سرعت از پردازنده اصلی به DMA درخواست دسترسی اضطراری به عملوندهای حافظه بزرگتر از یک کلمه(۱۶ بیت) می‌داد، سپس بالافاصله کنترل bus را رها می‌کرد و یه پردازنده اصلی می‌داد. کمک-پردازنده تا زمانی که دستورالعمل کمک-پردازنده تمام نشده بود مانع اجرای برنامه نمی‌شد و برنامه باید دو پردازنده را با هم همگام کند، همان‌طور که بالا ذکر شدا (در بخش «طراحی و توسعه»). یک پتانسیل کرش کردن وجود داشت اگر دستورالعمل کمک-پردازنده نتواند به کدی قابل فهم برای کمک-پردازنده دیکد کند. کمک-پردازنده‌های بعدی اینتل به این صورت به bus نمی‌شدند، ولی دستورالعمل‌ها را از طریق پردازنده اصلی با استفاده از پرت‌های ورودی/خروجی.
این به خطای زمان اجرا منجر شد، ولی از پتانسیل کرش کردن جلوگیری شد زیرا پردازنده می‌تواست دستورالعملی که کمک-پردازنده نپذیرفته بود، را نادیده بگیرد.
۸۰۸۷ با استفاده از کنترل کردن bus حین ریست کردن چرخه، قادر بود تشخیص دهد که به یک ۸۰۸۸ متصل است یا به یک ۸۰۸۶.
۸۰۸۷ در تئوری قادر به همزمان کار کردن بود در هالی که ۸۰۸۶/۸۰۸۸ قادر به پردازش دستورالعمل‌های بیشتر بودند. در عمل، این احتمال وجود داشت که برنامه کار نکند اگر قبل از مواجه شدن با دستورالعمل بعدی، دستور قبلی کامل نشده باشد. اسمبلر به‌طور اتوماتیک یک دستور 'FWAIT' بعد از هر آپکد کمک-پردازنده قرار می‌دهد و ۸۰۸۶/۸ را وادار به توقف اجرا می‌کند تا زمانی که ۸۰۸۷ سیگنال پایان بدهد این محدودیت در طرح‌های بعدی برداشته شد.

جانشین

همان‌طور که پردازنده‌های ۸۰۸۸ و ۸۰۸۶ با قطعات بعدی جایگزین شدند، ۸۰۸۷ هم جایگزین شد. باقی کمک-پردازنده‌های اینتل ۸۰۲۸۷، ۸۰۳۸۷ و ۸۰۱۸۷ بودند.
از ۸۰۴۸۶ به بعد پردازنده‌های اینتل از کمک-پردازنده‌های عدد اعشاری جداگانه استفاده نمی‌کردند؛ عملاً همه‌شان، کمک-پردازنده‌ها را در خودشان قرار داده بودند، بجز یک استثنای مهم که 80486SX، تغییر یافتهٔ 80486DX که FPU در آن غیرفعال شده بود. ۸۰۴۸۷ دراقع یک چیپ 80486DX با پین اضافی بود. هنگامی که نصب می‌شد پردازنده 80486SX را غیرفعال می‌کرد. پردازنده‌های 80486DX و Pentium و پردازنده‌های بعدی بر روی هسته پردازنده کارکرد عدد اعشاری داشتند.