x86: implement x87 fp instruction fsincos

This patch implements the fsincos instruction. The code was originally written
by Vince Weaver. Gabe had made some comments about the code, but those were
never addressed. This patch addresses those comments.
This commit is contained in:
Nilay Vaish 2012-12-30 12:45:45 -06:00
parent 3b01edd7fa
commit 23ba6fc5fb
3 changed files with 58 additions and 16 deletions

View file

@ -106,7 +106,7 @@ format WarnUnimpl {
0x0: fprem();
0x1: fyl2xp1();
0x2: fsqrt();
0x3: fsincos();
0x3: Inst::FSINCOS();
0x4: frndint();
0x5: fscale();
0x6: fsin();

View file

@ -38,7 +38,14 @@
microcode = '''
# FSIN
# FCOS
# FSINCOS
def macroop FSINCOS {
sinfp ufp1, st(0)
cosfp ufp2, st(0)
movfp st(0), ufp1
movfp st(-1), ufp2, spm=-1
};
# FPTAN
# FPATAN
'''

View file

@ -174,8 +174,40 @@ let {{
return cls
class FpUnaryOp(X86Microop):
__metaclass__ = FpOpMeta
# This class itself doesn't act as a microop
abstract = True
class FpOp(X86Microop):
# Default template parameter values
flag_code = ""
cond_check = "true"
else_code = ";"
def __init__(self, dest, src1, spm=0, \
SetStatus=False, dataSize="env.dataSize"):
self.dest = dest
self.src1 = src1
self.src2 = "InstRegIndex(0)"
self.spm = spm
self.dataSize = dataSize
if SetStatus:
self.className += "Flags"
if spm:
self.className += "Top"
def getAllocator(self, microFlags):
return '''new %(class_name)s(machInst, macrocodeBlock,
%(flags)s, %(src1)s, %(src2)s, %(dest)s,
%(dataSize)s, %(spm)d)''' % {
"class_name" : self.className,
"flags" : self.microFlagsText(microFlags),
"src1" : self.src1, "src2" : self.src2,
"dest" : self.dest,
"dataSize" : self.dataSize,
"spm" : self.spm}
class FpBinaryOp(X86Microop):
__metaclass__ = FpOpMeta
# This class itself doesn't act as a microop
abstract = True
@ -208,24 +240,27 @@ let {{
"dataSize" : self.dataSize,
"spm" : self.spm}
class Movfp(FpOp):
def __init__(self, dest, src1, spm=0, \
SetStatus=False, dataSize="env.dataSize"):
super(Movfp, self).__init__(dest, src1, "InstRegIndex(0)", \
spm, SetStatus, dataSize)
class Movfp(FpUnaryOp):
code = 'FpDestReg_uqw = FpSrcReg1_uqw;'
else_code = 'FpDestReg_uqw = FpDestReg_uqw;'
cond_check = "checkCondition(ccFlagBits | cfofBits | dfBit | \
ecfBit | ezfBit, src2)"
class Xorfp(FpOp):
class Xorfp(FpBinaryOp):
code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;'
class Sqrtfp(FpOp):
class Sqrtfp(FpBinaryOp):
code = 'FpDestReg = sqrt(FpSrcReg2);'
class Cosfp(FpUnaryOp):
code = 'FpDestReg = cos(FpSrcReg1);'
class Sinfp(FpUnaryOp):
code = 'FpDestReg = sin(FpSrcReg1);'
# Conversion microops
class ConvOp(FpOp):
class ConvOp(FpBinaryOp):
abstract = True
def __init__(self, dest, src1):
super(ConvOp, self).__init__(dest, src1, \
@ -258,19 +293,19 @@ let {{
# These need to consider size at some point. They'll always use doubles
# for the moment.
class addfp(FpOp):
class addfp(FpBinaryOp):
code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'
class mulfp(FpOp):
class mulfp(FpBinaryOp):
code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
class divfp(FpOp):
class divfp(FpBinaryOp):
code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
class subfp(FpOp):
class subfp(FpBinaryOp):
code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
class Compfp(FpOp):
class Compfp(FpBinaryOp):
def __init__(self, src1, src2, spm=0, setStatus=False, \
dataSize="env.dataSize"):
super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \