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++.
This commit is contained in:
Steve Reinhardt 2015-10-06 17:26:50 -07:00
parent 83e07c07f9
commit 57b9f53afa
5 changed files with 63 additions and 8 deletions

View file

@ -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();

View file

@ -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
};
'''

View file

@ -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

View file

@ -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

View file

@ -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