X86: Move the fp microops to their own file with their own base classes in C++ and python.

--HG--
extra : convert_revision : 9cd223f2005adb36fea2bb56fa39793a58ec958c
This commit is contained in:
Gabe Black 2007-09-19 18:27:55 -07:00
parent f3f3747431
commit a75b6f5106
13 changed files with 722 additions and 190 deletions

View file

@ -88,7 +88,9 @@ Import('*')
if env['TARGET_ISA'] == 'x86':
Source('emulenv.cc')
Source('floatregfile.cc')
Source('insts/microfpop.cc')
Source('insts/microldstop.cc')
Source('insts/microop.cc')
Source('insts/microregop.cc')
Source('insts/static_inst.cc')
Source('intregfile.cc')

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#include "arch/x86/insts/microfpop.hh"
#include "arch/x86/miscregs.hh"
#include <string>
namespace X86ISA
{
/*
uint64_t FpOp::genFlags(uint64_t oldFlags, uint64_t flagMask,
uint64_t _dest, uint64_t _src1, uint64_t _src2,
bool subtract) const
{
}
*/
std::string FpOp::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, instMnem, mnemonic);
printDestReg(response, 0, dataSize);
response << ", ";
printSrcReg(response, 0, dataSize);
response << ", ";
printSrcReg(response, 1, dataSize);
return response.str();
}
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_X86_INSTS_MICROFPOP_HH__
#define __ARCH_X86_INSTS_MICROFPOP_HH__
#include "arch/x86/insts/microop.hh"
namespace X86ISA
{
/**
* Base classes for FpOps which provides a generateDisassembly method.
*/
class FpOp : public X86MicroopBase
{
protected:
const RegIndex src1;
const RegIndex src2;
const RegIndex dest;
const uint8_t dataSize;
const int8_t spm;
// Constructor
FpOp(ExtMachInst _machInst,
const char *mnem, const char *_instMnem,
bool isMicro, bool isDelayed,
bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
uint8_t _dataSize, int8_t _spm,
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast,
__opClass),
src1(_src1), src2(_src2), dest(_dest),
dataSize(_dataSize), spm(_spm)
{}
/*
//Figure out what the condition code flags should be.
uint64_t genFlags(uint64_t oldFlags, uint64_t flagMask,
uint64_t _dest, uint64_t _src1, uint64_t _src2,
bool subtract = false) const;
bool checkCondition(uint64_t flags) const;*/
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
}
#endif //__ARCH_X86_INSTS_MICROFPOP_HH__

View file

@ -0,0 +1,139 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* The software must be used only for Non-Commercial Use which means any
* use which is NOT directed to receiving any direct monetary
* compensation for, or commercial advantage from such use. Illustrative
* examples of non-commercial use are academic research, personal study,
* teaching, education and corporate research & development.
* Illustrative examples of commercial use are distributing products for
* commercial advantage and providing services using the software for
* commercial advantage.
*
* If you wish to use this software or functionality therein that may be
* covered by patents for commercial use, please contact:
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. Redistributions
* in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. Neither the name of
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. No right of
* sublicense is granted herewith. Derivatives of the software and
* output created using the software may be prepared, but only for
* Non-Commercial Uses. Derivatives of the software may be shared with
* others provided: (i) the others agree to abide by the list of
* conditions herein which includes the Non-Commercial Use restrictions;
* and (ii) such Derivatives of the software include the above copyright
* notice to acknowledge the contribution from this software where
* applicable, this list of conditions and the disclaimer below.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#include "arch/x86/insts/microop.hh"
#include "arch/x86/miscregs.hh"
namespace X86ISA
{
bool X86MicroopBase::checkCondition(uint64_t flags, int condition) const
{
CCFlagBits ccflags = flags;
switch(condition)
{
case ConditionTests::True:
return true;
case ConditionTests::ECF:
return ccflags.ECF;
case ConditionTests::EZF:
return ccflags.EZF;
case ConditionTests::SZnZF:
return !(!ccflags.EZF & ccflags.ZF);
case ConditionTests::MSTRZ:
panic("This condition is not implemented!");
case ConditionTests::STRZ:
panic("This condition is not implemented!");
case ConditionTests::MSTRC:
panic("This condition is not implemented!");
case ConditionTests::STRZnEZF:
return !ccflags.EZF & ccflags.ZF;
//And no interrupts or debug traps are waiting
case ConditionTests::OF:
return ccflags.OF;
case ConditionTests::CF:
return ccflags.CF;
case ConditionTests::ZF:
return ccflags.ZF;
case ConditionTests::CvZF:
return ccflags.CF | ccflags.ZF;
case ConditionTests::SF:
return ccflags.SF;
case ConditionTests::PF:
return ccflags.PF;
case ConditionTests::SxOF:
return ccflags.SF ^ ccflags.OF;
case ConditionTests::SxOvZF:
return ccflags.SF ^ ccflags.OF | ccflags.ZF;
case ConditionTests::False:
return false;
case ConditionTests::NotECF:
return !ccflags.ECF;
case ConditionTests::NotEZF:
return !ccflags.EZF;
case ConditionTests::NotSZnZF:
return !ccflags.EZF & ccflags.ZF;
case ConditionTests::NotMSTRZ:
panic("This condition is not implemented!");
case ConditionTests::NotSTRZ:
panic("This condition is not implemented!");
case ConditionTests::NotMSTRC:
panic("This condition is not implemented!");
case ConditionTests::STRnZnEZF:
return !ccflags.EZF & !ccflags.ZF;
//And no interrupts or debug traps are waiting
case ConditionTests::NotOF:
return !ccflags.OF;
case ConditionTests::NotCF:
return !ccflags.CF;
case ConditionTests::NotZF:
return !ccflags.ZF;
case ConditionTests::NotCvZF:
return !(ccflags.CF | ccflags.ZF);
case ConditionTests::NotSF:
return !ccflags.SF;
case ConditionTests::NotPF:
return !ccflags.PF;
case ConditionTests::NotSxOF:
return !(ccflags.SF ^ ccflags.OF);
case ConditionTests::NotSxOvZF:
return !(ccflags.SF ^ ccflags.OF | ccflags.ZF);
}
panic("Unknown condition: %d\n", condition);
return true;
}
}

View file

@ -62,6 +62,47 @@
namespace X86ISA
{
namespace ConditionTests
{
enum CondTest {
True,
NotFalse = True,
ECF,
EZF,
SZnZF,
MSTRZ,
STRZ,
MSTRC,
STRZnEZF,
OF,
CF,
ZF,
CvZF,
SF,
PF,
SxOF,
SxOvZF,
False,
NotTrue = False,
NotECF,
NotEZF,
NotSZnZF,
NotMSTRZ,
NotSTRZ,
NotMSTRC,
STRnZnEZF,
NotOF,
NotCF,
NotZF,
NotCvZF,
NotSF,
NotPF,
NotSxOF,
NotSxOvZF
};
}
//A class which is the base of all x86 micro ops. It provides a function to
//set necessary flags appropriately.
class X86MicroopBase : public X86StaticInst
@ -94,6 +135,8 @@ namespace X86ISA
return ss.str();
}
bool checkCondition(uint64_t flags, int condition) const;
};
}

View file

@ -93,82 +93,6 @@ namespace X86ISA
return flags;
}
bool RegOpBase::checkCondition(uint64_t flags) const
{
CCFlagBits ccflags = flags;
switch(ext)
{
case ConditionTests::True:
return true;
case ConditionTests::ECF:
return ccflags.ECF;
case ConditionTests::EZF:
return ccflags.EZF;
case ConditionTests::SZnZF:
return !(!ccflags.EZF & ccflags.ZF);
case ConditionTests::MSTRZ:
panic("This condition is not implemented!");
case ConditionTests::STRZ:
panic("This condition is not implemented!");
case ConditionTests::MSTRC:
panic("This condition is not implemented!");
case ConditionTests::STRZnEZF:
return !ccflags.EZF & ccflags.ZF;
//And no interrupts or debug traps are waiting
case ConditionTests::OF:
return ccflags.OF;
case ConditionTests::CF:
return ccflags.CF;
case ConditionTests::ZF:
return ccflags.ZF;
case ConditionTests::CvZF:
return ccflags.CF | ccflags.ZF;
case ConditionTests::SF:
return ccflags.SF;
case ConditionTests::PF:
return ccflags.PF;
case ConditionTests::SxOF:
return ccflags.SF ^ ccflags.OF;
case ConditionTests::SxOvZF:
return ccflags.SF ^ ccflags.OF | ccflags.ZF;
case ConditionTests::False:
return false;
case ConditionTests::NotECF:
return !ccflags.ECF;
case ConditionTests::NotEZF:
return !ccflags.EZF;
case ConditionTests::NotSZnZF:
return !ccflags.EZF & ccflags.ZF;
case ConditionTests::NotMSTRZ:
panic("This condition is not implemented!");
case ConditionTests::NotSTRZ:
panic("This condition is not implemented!");
case ConditionTests::NotMSTRC:
panic("This condition is not implemented!");
case ConditionTests::STRnZnEZF:
return !ccflags.EZF & !ccflags.ZF;
//And no interrupts or debug traps are waiting
case ConditionTests::NotOF:
return !ccflags.OF;
case ConditionTests::NotCF:
return !ccflags.CF;
case ConditionTests::NotZF:
return !ccflags.ZF;
case ConditionTests::NotCvZF:
return !(ccflags.CF | ccflags.ZF);
case ConditionTests::NotSF:
return !ccflags.SF;
case ConditionTests::NotPF:
return !ccflags.PF;
case ConditionTests::NotSxOF:
return !(ccflags.SF ^ ccflags.OF);
case ConditionTests::NotSxOvZF:
return !(ccflags.SF ^ ccflags.OF | ccflags.ZF);
}
panic("Unknown condition: %d\n", ext);
return true;
}
std::string RegOp::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{

View file

@ -62,47 +62,6 @@
namespace X86ISA
{
namespace ConditionTests
{
enum CondTest {
True,
NotFalse = True,
ECF,
EZF,
SZnZF,
MSTRZ,
STRZ,
MSTRC,
STRZnEZF,
OF,
CF,
ZF,
CvZF,
SF,
PF,
SxOF,
SxOvZF,
False,
NotTrue = False,
NotECF,
NotEZF,
NotSZnZF,
NotMSTRZ,
NotSTRZ,
NotMSTRC,
STRnZnEZF,
NotOF,
NotCF,
NotZF,
NotCvZF,
NotSF,
NotPF,
NotSxOF,
NotSxOvZF
};
}
/**
* Base classes for RegOps which provides a generateDisassembly method.
*/
@ -136,7 +95,6 @@ namespace X86ISA
uint64_t genFlags(uint64_t oldFlags, uint64_t flagMask,
uint64_t _dest, uint64_t _src1, uint64_t _src2,
bool subtract = false) const;
bool checkCondition(uint64_t flags) const;
};
class RegOp : public RegOpBase

View file

@ -97,6 +97,7 @@ output header {{
#include <iostream>
#include "arch/x86/emulenv.hh"
#include "arch/x86/insts/microfpop.hh"
#include "arch/x86/insts/microldstop.hh"
#include "arch/x86/insts/microregop.hh"
#include "arch/x86/insts/static_inst.hh"

View file

@ -92,11 +92,3 @@ let {{
return 'new %s(machInst, %s)' % \
(self.className, mnemonic, self.microFlagsText(microFlags))
}};
//////////////////////////////////////////////////////////////////////////
//
// FpOp Microop templates
//
//////////////////////////////////////////////////////////////////////////
//TODO Actually write an fp microop base class.

View file

@ -0,0 +1,341 @@
// Copyright (c) 2007 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
// with or without modification, are permitted provided that the
// following conditions are met:
//
// The software must be used only for Non-Commercial Use which means any
// use which is NOT directed to receiving any direct monetary
// compensation for, or commercial advantage from such use. Illustrative
// examples of non-commercial use are academic research, personal study,
// teaching, education and corporate research & development.
// Illustrative examples of commercial use are distributing products for
// commercial advantage and providing services using the software for
// commercial advantage.
//
// If you wish to use this software or functionality therein that may be
// covered by patents for commercial use, please contact:
// Director of Intellectual Property Licensing
// Office of Strategy and Technology
// Hewlett-Packard Company
// 1501 Page Mill Road
// Palo Alto, California 94304
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. Redistributions
// in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution. Neither the name of
// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission. No right of
// sublicense is granted herewith. Derivatives of the software and
// output created using the software may be prepared, but only for
// Non-Commercial Uses. Derivatives of the software may be shared with
// others provided: (i) the others agree to abide by the list of
// conditions herein which includes the Non-Commercial Use restrictions;
// and (ii) such Derivatives of the software include the above copyright
// notice to acknowledge the contribution from this software where
// applicable, this list of conditions and the disclaimer below.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Gabe Black
//////////////////////////////////////////////////////////////////////////
//
// FpOp Microop templates
//
//////////////////////////////////////////////////////////////////////////
def template MicroFpOpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
DPRINTF(X86, "The data size is %d\n", dataSize);
%(op_decl)s;
%(op_rd)s;
if(%(cond_check)s)
{
%(code)s;
%(flag_code)s;
%(top_code)s;
}
else
{
%(else_code)s;
}
//Write the resulting state to the execution context
if(fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
def template MicroFpOpDeclare {{
class %(class_name)s : public %(base_class)s
{
protected:
void buildMe();
public:
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
uint8_t _dataSize, int8_t _spm);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
uint8_t _dataSize, int8_t _spm);
%(BasicExecDeclare)s
};
}};
def template MicroFpOpConstructor {{
inline void %(class_name)s::buildMe()
{
%(constructor)s;
}
inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
uint8_t _dataSize, int8_t _spm) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false,
_src1, _src2, _dest, _dataSize, _spm,
%(op_class)s)
{
buildMe();
}
inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest,
uint8_t _dataSize, int8_t _spm) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast,
_src1, _src2, _dest, _dataSize, _spm,
%(op_class)s)
{
buildMe();
}
}};
let {{
# Make these empty strings so that concatenating onto
# them will always work.
header_output = ""
decoder_output = ""
exec_output = ""
class FpOpMeta(type):
def buildCppClasses(self, name, Name, suffix, \
code, flag_code, cond_check, else_code):
# Globals to stick the output in
global header_output
global decoder_output
global exec_output
# Stick all the code together so it can be searched at once
allCode = "|".join((code, flag_code, cond_check, else_code))
# If there's something optional to do with flags, generate
# a version without it and fix up this version to use it.
if flag_code is not "" or cond_check is not "true":
self.buildCppClasses(name, Name, suffix,
code, "", "true", else_code)
suffix = "Flags" + suffix
base = "X86ISA::FpOp"
# Get everything ready for the substitution
iop_top = InstObjParams(name, Name + suffix + "Top", base,
{"code" : code,
"flag_code" : flag_code,
"cond_check" : cond_check,
"else_code" : else_code,
"top_code" : "TOP = (TOP + spm + 8) % 8;"})
iop = InstObjParams(name, Name + suffix, base,
{"code" : code,
"flag_code" : flag_code,
"cond_check" : cond_check,
"else_code" : else_code,
"top_code" : ";"})
# Generate the actual code (finally!)
header_output += MicroFpOpDeclare.subst(iop_top)
decoder_output += MicroFpOpConstructor.subst(iop_top)
exec_output += MicroFpOpExecute.subst(iop_top)
header_output += MicroFpOpDeclare.subst(iop)
decoder_output += MicroFpOpConstructor.subst(iop)
exec_output += MicroFpOpExecute.subst(iop)
def __new__(mcls, Name, bases, dict):
abstract = False
name = Name.lower()
if "abstract" in dict:
abstract = dict['abstract']
del dict['abstract']
cls = super(FpOpMeta, mcls).__new__(mcls, Name, bases, dict)
if not abstract:
cls.className = Name
cls.mnemonic = name
code = cls.code
flag_code = cls.flag_code
cond_check = cls.cond_check
else_code = cls.else_code
# Set up the C++ classes
mcls.buildCppClasses(cls, name, Name, "",
code, flag_code, cond_check, else_code)
# Hook into the microassembler dict
global microopClasses
microopClasses[name] = cls
return cls
class FpOp(X86Microop):
__metaclass__ = FpOpMeta
# This class itself doesn't act as a microop
abstract = True
# Default template parameter values
flag_code = ""
cond_check = "true"
else_code = ";"
def __init__(self, dest, src1, src2, spm=0, \
SetStatus=False, dataSize="env.dataSize"):
self.dest = dest
self.src1 = src1
self.src2 = src2
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, mnemonic
%(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 Movfp(FpOp):
def __init__(self, dest, src1, flags=0, spm=0, \
SetStatus=False, dataSize="env.dataSize"):
super(Movfp, self).__init__(dest, src1, flags, \
spm, SetStatus, dataSize)
code = 'FpDestReg.uqw = FpSrcReg2.uqw;'
else_code = 'FpDestReg.uqw = FpDestReg.uqw;'
cond_check = "checkCondition(ccFlagBits, src2)"
class Xorfp(FpOp):
code = 'FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;'
class Sqrtfp(FpOp):
code = 'FpDestReg = sqrt(FpSrcReg2);'
# Conversion microops
class ConvOp(FpOp):
abstract = True
def __init__(self, dest, src1):
super(ConvOp, self).__init__(dest, src1, "(int)FLOATREG_MICROFP0")
# These probably shouldn't look at the ExtMachInst directly to figure
# out what size to use and should instead delegate that to the macroop's
# constructor. That would be more efficient, and it would make the
# microops a little more modular.
class cvtf_i2d(ConvOp):
code = '''
X86IntReg intReg = SSrcReg1;
if (REX_W)
FpDestReg = intReg.SR;
else
FpDestReg = intReg.SE;
'''
class cvtf_i2d_hi(ConvOp):
code = 'FpDestReg = bits(SSrcReg1, 63, 32);'
class cvtf_d2i(ConvOp):
code = '''
int64_t intSrcReg1 = static_cast<int64_t>(FpSrcReg1);
if (REX_W)
SDestReg = intSrcReg1;
else
SDestReg = merge(SDestReg, intSrcReg1, 4);
'''
# These need to consider size at some point. They'll always use doubles
# for the moment.
class addfp(FpOp):
code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'
class mulfp(FpOp):
code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
class divfp(FpOp):
code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
class subfp(FpOp):
code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
class Compfp(FpOp):
def __init__(self, src1, src2, spm=0, setStatus=False, \
dataSize="env.dataSize"):
super(Compfp, self).__init__("(int)FLOATREG_MICROFP0", \
src1, src2, spm, setStatus, dataSize)
# This class sets the condition codes in rflags according to the
# rules for comparing floating point.
code = '''
// ZF PF CF
// Unordered 1 1 1
// Greater than 0 0 0
// Less than 0 0 1
// Equal 1 0 0
// OF = SF = AF = 0
ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
ZFBit | PFBit | CFBit);
if (isnan(FpSrcReg1) || isnan(FpSrcReg2))
ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
else if(FpSrcReg1 < FpSrcReg2)
ccFlagBits = ccFlagBits | CFBit;
else if(FpSrcReg1 == FpSrcReg2)
ccFlagBits = ccFlagBits | ZFBit;
'''
}};

View file

@ -56,6 +56,9 @@
//Common microop stuff
##include "base.isa"
//Floating point definitions
##include "fpop.isa"
//Register microop definitions
##include "regop.isa"

View file

@ -458,7 +458,7 @@ let {{
class CondRegOp(RegOp):
abstract = True
cond_check = "checkCondition(ccFlagBits)"
cond_check = "checkCondition(ccFlagBits, ext)"
class RdRegOp(RegOp):
abstract = True
@ -873,67 +873,4 @@ let {{
class Zext(RegOp):
code = 'DestReg = bits(psrc1, imm8-1, 0);'
class Compfp(WrRegOp):
# This class sets the condition codes in rflags according to the
# rules for comparing floating point.
code = '''
// ZF PF CF
// Unordered 1 1 1
// Greater than 0 0 0
// Less than 0 0 1
// Equal 1 0 0
// OF = SF = AF = 0
ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
ZFBit | PFBit | CFBit);
if (isnan(FpSrcReg1) || isnan(FpSrcReg2))
ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
else if(FpSrcReg1 < FpSrcReg2)
ccFlagBits = ccFlagBits | CFBit;
else if(FpSrcReg1 == FpSrcReg2)
ccFlagBits = ccFlagBits | ZFBit;
'''
class Xorfp(RegOp):
code = 'FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;'
class Sqrtfp(RegOp):
code = 'FpDestReg = sqrt(FpSrcReg2);'
class Movfp(CondRegOp):
code = 'FpDestReg.uqw = FpSrcReg2.uqw;'
else_code = 'FpDestReg.uqw = FpDestReg.uqw;'
# Conversion microops
class ConvOp(RegOp):
abstract = True
def __init__(self, dest, src1):
super(ConvOp, self).__init__(dest, src1, "NUM_INTREGS")
#FIXME This needs to always use 32 bits unless REX.W is present
class cvtf_i2d(ConvOp):
code = 'FpDestReg = spsrc1;'
class cvtf_i2d_hi(ConvOp):
code = 'FpDestReg = bits(SrcReg1, 63, 32);'
class cvtf_d2i(ConvOp):
code = '''
int64_t intSrcReg1 = static_cast<int64_t>(FpSrcReg1);
DestReg = merge(DestReg, intSrcReg1, dataSize);
'''
# These need to consider size at some point. They'll always use doubles
# for the moment.
class addfp(RegOp):
code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'
class mulfp(RegOp):
code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
class divfp(RegOp):
code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
class subfp(RegOp):
code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
}};

View file

@ -96,10 +96,13 @@ def operand_types {{
def operands {{
'SrcReg1': ('IntReg', 'uqw', 'INTREG_FOLDED(src1, foldOBit)', 'IsInteger', 1),
'SSrcReg1': ('IntReg', 'uqw', 'src1', 'IsInteger', 1),
'SrcReg2': ('IntReg', 'uqw', 'INTREG_FOLDED(src2, foldOBit)', 'IsInteger', 2),
'SSrcReg2': ('IntReg', 'uqw', 'src2', 'IsInteger', 1),
'Index': ('IntReg', 'uqw', 'INTREG_FOLDED(index, foldABit)', 'IsInteger', 3),
'Base': ('IntReg', 'uqw', 'INTREG_FOLDED(base, foldABit)', 'IsInteger', 4),
'DestReg': ('IntReg', 'uqw', 'INTREG_FOLDED(dest, foldOBit)', 'IsInteger', 5),
'SDestReg': ('IntReg', 'uqw', 'dest', 'IsInteger', 5),
'Data': ('IntReg', 'uqw', 'INTREG_FOLDED(data, foldOBit)', 'IsInteger', 6),
'ProdLow': ('IntReg', 'uqw', 'INTREG_IMPLICIT(0)', 'IsInteger', 7),
'ProdHi': ('IntReg', 'uqw', 'INTREG_IMPLICIT(1)', 'IsInteger', 8),