From 57b9f53afa5660152a77b7f3b7affb39f5b0e176 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 6 Oct 2015 17:26:50 -0700 Subject: [PATCH] x86: implement fild, fucomi, and fucomip x87 insts fild loads an integer value into the x87 top of stack register. fucomi/fucomip compare two x87 register values (the latter also doing a stack pop). These instructions are used by some versions of GNU libstdc++. --- src/arch/x86/isa/decoder/x87.isa | 17 ++++++++++++----- .../floating_point_unordered_compare.py | 16 ++++++++++++++-- .../convert_and_load_or_store_integer.py | 17 ++++++++++++++++- src/arch/x86/isa/microops/fpop.isa | 2 ++ src/arch/x86/isa/microops/ldstop.isa | 19 +++++++++++++++++++ 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/arch/x86/isa/decoder/x87.isa b/src/arch/x86/isa/decoder/x87.isa index b53c48e78..4283d8d91 100644 --- a/src/arch/x86/isa/decoder/x87.isa +++ b/src/arch/x86/isa/decoder/x87.isa @@ -1,5 +1,7 @@ // Copyright (c) 2007 The Hewlett-Packard Development Company // Copyright (c) 2012-13 Mark D. Hill and David A. Wood +// Copyright (c) 2015 Advanced Micro Devices, Inc. +// // All rights reserved. // // The license below extends only to copyright in the software and shall @@ -36,6 +38,7 @@ // // Authors: Gabe Black // Nilay Vaish +// Steve Reinhardt format WarnUnimpl { 0x1B: decode OPCODE_OP_BOTTOM3 { @@ -174,7 +177,7 @@ format WarnUnimpl { 0x3: decode MODRM_REG { 0x0: decode MODRM_MOD { 0x3: fcmovnb(); - default: fild(); + default: Inst::FILD(Md); // 32-bit int } 0x1: decode MODRM_MOD { 0x3: fcmovne(); @@ -197,7 +200,9 @@ format WarnUnimpl { default: Inst::UD2(); } 0x5: decode MODRM_MOD { - 0x3: fucomi(); + // 'R' insists on having a size qualifier, so I picked 'q', + // but I don't think it has any effect + 0x3: Inst::FUCOMI(Rq); // 80-bit load default: Inst::FLD80(M); } @@ -331,7 +336,7 @@ format WarnUnimpl { // The ffreep instruction isn't entirely real. It should work // the same as ffree but then also pop the register stack. 0x3: ffreep(); - default: fild(); + default: Inst::FILD(Mw); // 16-bit int } 0x1: decode MODRM_MOD { 0x3: Inst::UD2(); @@ -353,8 +358,10 @@ format WarnUnimpl { default: fbld(); } 0x5: decode MODRM_MOD { - 0x3: fucomip(); - default: fild(); + // 'R' insists on having a size qualifier, so I picked 'q', + // but I don't think it has any effect + 0x3: Inst::FUCOMIP(Rq); + default: Inst::FILD(Mq); // 64-bit int } 0x6: decode MODRM_MOD { 0x3: fcomip(); diff --git a/src/arch/x86/isa/insts/x87/compare_and_test/floating_point_unordered_compare.py b/src/arch/x86/isa/insts/x87/compare_and_test/floating_point_unordered_compare.py index 8cca0582b..7007c2d74 100644 --- a/src/arch/x86/isa/insts/x87/compare_and_test/floating_point_unordered_compare.py +++ b/src/arch/x86/isa/insts/x87/compare_and_test/floating_point_unordered_compare.py @@ -1,4 +1,6 @@ # Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2015 Advanced Micro Devices, Inc. +# # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -34,11 +36,21 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Gabe Black +# Steve Reinhardt microcode = ''' # FUCOM # FUCOMP # FUCOMPP -# FUCOMI -# FUCOMIP + +# fucomi +def macroop FUCOMI_R { + compfp st(0), sti +}; + +# fucomi with stack pop (caused by spm=1) +def macroop FUCOMIP_R { + compfp st(0), sti, spm=1 +}; + ''' diff --git a/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/convert_and_load_or_store_integer.py b/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/convert_and_load_or_store_integer.py index 38f179d74..9bf4ec614 100644 --- a/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/convert_and_load_or_store_integer.py +++ b/src/arch/x86/isa/insts/x87/data_transfer_and_conversion/convert_and_load_or_store_integer.py @@ -1,4 +1,6 @@ # Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2015 Advanced Micro Devices, Inc. +# # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -34,9 +36,22 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Gabe Black +# Steve Reinhardt microcode = ''' -# FILD +# fild common case +def macroop FILD_M { + ldifp87 ufp1, seg, sib, disp + movfp st(-1), ufp1, spm=-1 +}; + +# fild with RIP-relative addressing +def macroop FILD_P { + rdip t7 + ldifp87 ufp1, seg, riprel, disp + movfp st(-1), ufp1, spm=-1 +}; + # FIST # FISTP # FISTTP diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa index 39162d392..6ba292977 100644 --- a/src/arch/x86/isa/microops/fpop.isa +++ b/src/arch/x86/isa/microops/fpop.isa @@ -1,5 +1,7 @@ // Copyright (c) 2007 The Hewlett-Packard Development Company // Copyright (c) 2012-2013 Mark D. Hill and David A. Wood +// Copyright (c) 2015 Advanced Micro Devices, Inc. +// // All rights reserved. // // The license below extends only to copyright in the software and shall diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index bccec36fe..a7c201f44 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -427,6 +427,25 @@ let {{ } ''', big = False) + # Load integer from memory into x87 top-of-stack register. + # Used to implement fild instruction. + defineMicroLoadOp('Ldifp87', code=''' + switch (dataSize) + { + case 2: + FpData_df = (int64_t)sext<16>(Mem); + break; + case 4: + FpData_df = (int64_t)sext<32>(Mem); + break; + case 8: + FpData_df = (int64_t)Mem; + break; + default: + panic("Unhandled data size in LdIFp87.\\n"); + } + ''', big = False) + def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"): global header_output global decoder_output