x86: implement some of the x87 instructions

This patch implements ftan, fprem, fyl2x, fld* floating-point instructions.
This commit is contained in:
Nilay Vaish 2013-03-11 13:15:46 -05:00
parent 82f600e02d
commit 5c940fec0a
10 changed files with 115 additions and 25 deletions

View file

@ -1,4 +1,5 @@
// Copyright (c) 2007 The Hewlett-Packard Development Company
// Copyright (c) 2012-13 Mark D. Hill and David A. Wood
// All rights reserved.
//
// The license below extends only to copyright in the software and shall
@ -34,11 +35,13 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Gabe Black
// Nilay Vaish
format WarnUnimpl {
0x1B: decode OPCODE_OP_BOTTOM3 {
//0x0: esc0();
0x0: decode MODRM_REG {
// ST(0) = ST(0) + 32-bit Mem
0x0: fadd();
0x1: fmul();
0x2: fcom();
@ -50,7 +53,11 @@ format WarnUnimpl {
}
//0x1: esc1();
0x1: decode MODRM_REG {
0x0: fld();
0x0: decode MODRM_MOD {
0x3: Inst::FLD(Eq);
// 32-bit load
default: Inst::FLD(Md);
}
0x1: decode MODRM_MOD {
0x3: fxch();
default: Inst::UD2();
@ -78,24 +85,24 @@ format WarnUnimpl {
}
0x5: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x0: fld1();
0x1: fldl2t();
0x2: fldl2e();
0x3: fldpi();
0x4: fldlg2();
0x5: fldln2();
0x6: fldz();
0x0: Inst::FLD1();
0x1: Inst::FLDL2T();
0x2: Inst::FLDL2E();
0x3: Inst::FLDPI();
0x4: Inst::FLDLG2();
0x5: Inst::FLDLN2();
0x6: Inst::FLDZ();
}
default: fldcw_Mw();
default: Inst::FLDCW(Mw);
}
0x6: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x0: f2xm1();
0x1: fyl2x();
0x2: fptan();
0x1: Inst::FYL2X();
0x2: Inst::FPTAN();
0x3: fpatan();
0x4: fxtract();
0x5: fprem1();
0x5: Inst::FPREM1();
0x6: fdecstp();
0x7: fincstp();
}
@ -103,7 +110,7 @@ format WarnUnimpl {
}
0x7: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x0: fprem();
0x0: Inst::FPREM();
0x1: fyl2xp1();
0x2: fsqrt();
0x3: Inst::FSINCOS();
@ -181,6 +188,7 @@ format WarnUnimpl {
}
0x5: decode MODRM_MOD {
0x3: fucomi();
// 80-bit load
default: fld();
}
0x6: decode MODRM_MOD {
@ -225,6 +233,7 @@ format WarnUnimpl {
0x5: decode MODRM_REG {
0x0: decode MODRM_MOD {
0x3: ffree();
// 64-bit load
default: Inst::FLD(Mq);
}
0x1: decode MODRM_MOD {

View file

@ -36,6 +36,11 @@
# Authors: Gabe Black
microcode = '''
# FPREM
# FPREM1
def macroop FPREM {
premfp st(0), st(1), st(0)
};
def macroop FPREM1 {
premfp st(0), st(1), st(0)
};
'''

View file

@ -36,7 +36,17 @@
# Authors: Gabe Black
microcode = '''
# FLDCW
def macroop FLDCW_M {
ld t1, seg, sib, disp, dataSize=2
wrval fcw, t1
};
def macroop FLDCW_P {
ld t1, seg, sib, disp, dataSize=2
wrval fcw, t1
};
# FSTCW
def macroop FNSTCW_M {

View file

@ -47,6 +47,10 @@ def macroop FLD_P {
movfp st(-1), ufp1, spm=-1
};
def macroop FLD_R {
movfp st(-1), sti, spm=-1
};
def macroop FST_R {
movfp sti, st(0)
};

View file

@ -1,4 +1,5 @@
# Copyright (c) 2007 The Hewlett-Packard Development Company
# Copyright (c) 2013 Mark D. Hill and David A. Wood
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@ -34,9 +35,23 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Gabe Black
# Nilay Vaish
microcode = '''
# FLDZ
# FLD1
# FLDPI
def macroop FLDZ {
limm ufp1, "double(0)"
movfp st(-1), ufp1, spm=-1
};
def macroop FLD1 {
limm ufp1, "double(1)"
movfp st(-1), ufp1, spm=-1
};
def macroop FLDPI {
limm ufp1, "double(3.14159265359)"
movfp st(-1), ufp1, spm=-1
};
'''

View file

@ -1,4 +1,5 @@
# Copyright (c) 2007 The Hewlett-Packard Development Company
# Copyright (c) 2013 Mark D. Hill and David A. Wood
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@ -34,10 +35,28 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Gabe Black
# Nilay Vaish
microcode = '''
# FLDL2E
# FLDL2T
# FLDLG2
# FLDLN2
def macroop FLDL2E {
limm ufp1, "double(1.44269504089)"
movfp st(-1), ufp1, spm=-1
};
def macroop FLDL2T {
limm ufp1, "double(3.32192809489)"
movfp st(-1), ufp1, spm=-1
};
def macroop FLDLG2 {
limm ufp1, "double(0.30102999566)"
movfp st(-1), ufp1, spm=-1
};
def macroop FLDLN2 {
limm ufp1, "double(0.69314718056)"
movfp st(-1), ufp1, spm=-1
};
'''

View file

@ -38,6 +38,10 @@
microcode = '''
# F2XM1
# FSCALE
# FYL2X
def macroop FYL2X {
yl2xfp st(1), st(0), st(1), spm=1
};
# FYL2XP1
'''

View file

@ -1,4 +1,5 @@
# Copyright (c) 2007 The Hewlett-Packard Development Company
# Copyright (c) 2012-13 Mark D. Hill and David A. Wood
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@ -34,6 +35,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Gabe Black
# Nilay Vaish
microcode = '''
def macroop FSIN {
@ -51,6 +53,11 @@ def macroop FSINCOS {
movfp st(-1), ufp2, spm=-1
};
# FPTAN
def macroop FPTAN {
tanfp st(0), st(0)
limm ufp1, "double(1)"
movfp st(-1), ufp1, spm=-1
};
# FPATAN
'''

View file

@ -1,4 +1,5 @@
// Copyright (c) 2007 The Hewlett-Packard Development Company
// Copyright (c) 2012-2013 Mark D. Hill and David A. Wood
// All rights reserved.
//
// The license below extends only to copyright in the software and shall
@ -34,6 +35,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Gabe Black
// Nilay Vaish
//////////////////////////////////////////////////////////////////////////
//
@ -258,6 +260,9 @@ let {{
class Sinfp(FpUnaryOp):
code = 'FpDestReg = sin(FpSrcReg1);'
class Tanfp(FpUnaryOp):
code = 'FpDestReg = tan(FpSrcReg1);'
# Conversion microops
class ConvOp(FpBinaryOp):
@ -305,6 +310,17 @@ let {{
class subfp(FpBinaryOp):
code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
class Yl2xFp(FpBinaryOp):
code = '''
FpDestReg = FpSrcReg2 * (log(FpSrcReg1) / log(2));
'''
class PremFp(FpBinaryOp):
code = '''
FpDestReg = fmod(FpSrcReg1, FpSrcReg2);
DPRINTF(X86, "src1: %lf, src2: %lf, dest: %lf\\n", FpSrcReg1, FpSrcReg2, FpDestReg);
'''
class Compfp(FpBinaryOp):
def __init__(self, src1, src2, spm=0, setStatus=False, \
dataSize="env.dataSize"):

View file

@ -163,6 +163,7 @@ def operands {{
'TOP': controlReg('MISCREG_X87_TOP', 66, ctype='ub'),
'FSW': controlReg('MISCREG_FSW', 67, ctype='uw'),
'FTW': controlReg('MISCREG_FTW', 68, ctype='uw'),
'FCW': controlReg('MISCREG_FCW', 69, ctype='uw'),
# The segment base as used by memory instructions.
'SegBase': controlReg('MISCREG_SEG_EFF_BASE(segment)', 70),