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:
parent
3b01edd7fa
commit
23ba6fc5fb
3 changed files with 58 additions and 16 deletions
|
@ -106,7 +106,7 @@ format WarnUnimpl {
|
||||||
0x0: fprem();
|
0x0: fprem();
|
||||||
0x1: fyl2xp1();
|
0x1: fyl2xp1();
|
||||||
0x2: fsqrt();
|
0x2: fsqrt();
|
||||||
0x3: fsincos();
|
0x3: Inst::FSINCOS();
|
||||||
0x4: frndint();
|
0x4: frndint();
|
||||||
0x5: fscale();
|
0x5: fscale();
|
||||||
0x6: fsin();
|
0x6: fsin();
|
||||||
|
|
|
@ -38,7 +38,14 @@
|
||||||
microcode = '''
|
microcode = '''
|
||||||
# FSIN
|
# FSIN
|
||||||
# FCOS
|
# FCOS
|
||||||
# FSINCOS
|
|
||||||
|
def macroop FSINCOS {
|
||||||
|
sinfp ufp1, st(0)
|
||||||
|
cosfp ufp2, st(0)
|
||||||
|
movfp st(0), ufp1
|
||||||
|
movfp st(-1), ufp2, spm=-1
|
||||||
|
};
|
||||||
|
|
||||||
# FPTAN
|
# FPTAN
|
||||||
# FPATAN
|
# FPATAN
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -174,8 +174,40 @@ let {{
|
||||||
|
|
||||||
return cls
|
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
|
__metaclass__ = FpOpMeta
|
||||||
# This class itself doesn't act as a microop
|
# This class itself doesn't act as a microop
|
||||||
abstract = True
|
abstract = True
|
||||||
|
@ -208,24 +240,27 @@ let {{
|
||||||
"dataSize" : self.dataSize,
|
"dataSize" : self.dataSize,
|
||||||
"spm" : self.spm}
|
"spm" : self.spm}
|
||||||
|
|
||||||
class Movfp(FpOp):
|
class Movfp(FpUnaryOp):
|
||||||
def __init__(self, dest, src1, spm=0, \
|
|
||||||
SetStatus=False, dataSize="env.dataSize"):
|
|
||||||
super(Movfp, self).__init__(dest, src1, "InstRegIndex(0)", \
|
|
||||||
spm, SetStatus, dataSize)
|
|
||||||
code = 'FpDestReg_uqw = FpSrcReg1_uqw;'
|
code = 'FpDestReg_uqw = FpSrcReg1_uqw;'
|
||||||
else_code = 'FpDestReg_uqw = FpDestReg_uqw;'
|
else_code = 'FpDestReg_uqw = FpDestReg_uqw;'
|
||||||
cond_check = "checkCondition(ccFlagBits | cfofBits | dfBit | \
|
cond_check = "checkCondition(ccFlagBits | cfofBits | dfBit | \
|
||||||
ecfBit | ezfBit, src2)"
|
ecfBit | ezfBit, src2)"
|
||||||
|
|
||||||
class Xorfp(FpOp):
|
class Xorfp(FpBinaryOp):
|
||||||
code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;'
|
code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;'
|
||||||
|
|
||||||
class Sqrtfp(FpOp):
|
class Sqrtfp(FpBinaryOp):
|
||||||
code = 'FpDestReg = sqrt(FpSrcReg2);'
|
code = 'FpDestReg = sqrt(FpSrcReg2);'
|
||||||
|
|
||||||
|
class Cosfp(FpUnaryOp):
|
||||||
|
code = 'FpDestReg = cos(FpSrcReg1);'
|
||||||
|
|
||||||
|
class Sinfp(FpUnaryOp):
|
||||||
|
code = 'FpDestReg = sin(FpSrcReg1);'
|
||||||
|
|
||||||
|
|
||||||
# Conversion microops
|
# Conversion microops
|
||||||
class ConvOp(FpOp):
|
class ConvOp(FpBinaryOp):
|
||||||
abstract = True
|
abstract = True
|
||||||
def __init__(self, dest, src1):
|
def __init__(self, dest, src1):
|
||||||
super(ConvOp, self).__init__(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
|
# These need to consider size at some point. They'll always use doubles
|
||||||
# for the moment.
|
# for the moment.
|
||||||
class addfp(FpOp):
|
class addfp(FpBinaryOp):
|
||||||
code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'
|
code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'
|
||||||
|
|
||||||
class mulfp(FpOp):
|
class mulfp(FpBinaryOp):
|
||||||
code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
|
code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
|
||||||
|
|
||||||
class divfp(FpOp):
|
class divfp(FpBinaryOp):
|
||||||
code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
|
code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
|
||||||
|
|
||||||
class subfp(FpOp):
|
class subfp(FpBinaryOp):
|
||||||
code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
|
code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
|
||||||
|
|
||||||
class Compfp(FpOp):
|
class Compfp(FpBinaryOp):
|
||||||
def __init__(self, src1, src2, spm=0, setStatus=False, \
|
def __init__(self, src1, src2, spm=0, setStatus=False, \
|
||||||
dataSize="env.dataSize"):
|
dataSize="env.dataSize"):
|
||||||
super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \
|
super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \
|
||||||
|
|
Loading…
Reference in a new issue