2009-08-18 03:15:18 +02:00
|
|
|
/// Copyright (c) 2009 The Regents of The University of Michigan
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are
|
|
|
|
// met: 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 holders nor the names of its
|
|
|
|
// contributors may be used to endorse or promote products derived from
|
|
|
|
// this software without specific prior written permission.
|
|
|
|
//
|
|
|
|
// 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
|
|
|
|
|
|
|
|
def template MediaOpExecute {{
|
|
|
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
|
|
|
Trace::InstRecord *traceData) const
|
|
|
|
{
|
|
|
|
Fault fault = NoFault;
|
|
|
|
|
|
|
|
%(op_decl)s;
|
|
|
|
%(op_rd)s;
|
|
|
|
|
|
|
|
%(code)s;
|
|
|
|
|
|
|
|
//Write the resulting state to the execution context
|
|
|
|
if(fault == NoFault)
|
|
|
|
{
|
|
|
|
%(op_wb)s;
|
|
|
|
}
|
|
|
|
return fault;
|
|
|
|
}
|
|
|
|
}};
|
|
|
|
|
|
|
|
def template MediaOpRegDeclare {{
|
|
|
|
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,
|
|
|
|
InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
|
2009-08-18 03:27:44 +02:00
|
|
|
uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
|
2009-08-18 03:15:18 +02:00
|
|
|
|
|
|
|
%(class_name)s(ExtMachInst _machInst,
|
|
|
|
const char * instMnem,
|
|
|
|
InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
|
2009-08-18 03:27:44 +02:00
|
|
|
uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
|
2009-08-18 03:15:18 +02:00
|
|
|
|
|
|
|
%(BasicExecDeclare)s
|
|
|
|
};
|
|
|
|
}};
|
|
|
|
|
|
|
|
def template MediaOpImmDeclare {{
|
|
|
|
|
|
|
|
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,
|
|
|
|
InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
|
2009-08-18 03:27:44 +02:00
|
|
|
uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
|
2009-08-18 03:15:18 +02:00
|
|
|
|
|
|
|
%(class_name)s(ExtMachInst _machInst,
|
|
|
|
const char * instMnem,
|
|
|
|
InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
|
2009-08-18 03:27:44 +02:00
|
|
|
uint8_t _srcSize, uint8_t _destSize, uint16_t _ext);
|
2009-08-18 03:15:18 +02:00
|
|
|
|
|
|
|
%(BasicExecDeclare)s
|
|
|
|
};
|
|
|
|
}};
|
|
|
|
|
|
|
|
def template MediaOpRegConstructor {{
|
|
|
|
|
|
|
|
inline void %(class_name)s::buildMe()
|
|
|
|
{
|
|
|
|
%(constructor)s;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline %(class_name)s::%(class_name)s(
|
|
|
|
ExtMachInst machInst, const char * instMnem,
|
|
|
|
InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
|
2009-08-18 03:27:44 +02:00
|
|
|
uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
|
2009-08-18 03:15:18 +02:00
|
|
|
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
|
|
|
false, false, false, false,
|
2009-08-18 03:27:44 +02:00
|
|
|
_src1, _src2, _dest, _srcSize, _destSize, _ext,
|
2009-08-18 03:15:18 +02:00
|
|
|
%(op_class)s)
|
|
|
|
{
|
|
|
|
buildMe();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline %(class_name)s::%(class_name)s(
|
|
|
|
ExtMachInst machInst, const char * instMnem,
|
|
|
|
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
|
|
|
InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
|
2009-08-18 03:27:44 +02:00
|
|
|
uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
|
2009-08-18 03:15:18 +02:00
|
|
|
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
|
|
|
isMicro, isDelayed, isFirst, isLast,
|
2009-08-18 03:27:44 +02:00
|
|
|
_src1, _src2, _dest, _srcSize, _destSize, _ext,
|
2009-08-18 03:15:18 +02:00
|
|
|
%(op_class)s)
|
|
|
|
{
|
|
|
|
buildMe();
|
|
|
|
}
|
|
|
|
}};
|
|
|
|
|
|
|
|
def template MediaOpImmConstructor {{
|
|
|
|
|
|
|
|
inline void %(class_name)s::buildMe()
|
|
|
|
{
|
|
|
|
%(constructor)s;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline %(class_name)s::%(class_name)s(
|
|
|
|
ExtMachInst machInst, const char * instMnem,
|
|
|
|
InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
|
2009-08-18 03:27:44 +02:00
|
|
|
uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
|
2009-08-18 03:15:18 +02:00
|
|
|
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
|
|
|
false, false, false, false,
|
2009-08-18 03:27:44 +02:00
|
|
|
_src1, _imm8, _dest, _srcSize, _destSize, _ext,
|
2009-08-18 03:15:18 +02:00
|
|
|
%(op_class)s)
|
|
|
|
{
|
|
|
|
buildMe();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline %(class_name)s::%(class_name)s(
|
|
|
|
ExtMachInst machInst, const char * instMnem,
|
|
|
|
bool isMicro, bool isDelayed, bool isFirst, bool isLast,
|
|
|
|
InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
|
2009-08-18 03:27:44 +02:00
|
|
|
uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) :
|
2009-08-18 03:15:18 +02:00
|
|
|
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
|
|
|
|
isMicro, isDelayed, isFirst, isLast,
|
2009-08-18 03:27:44 +02:00
|
|
|
_src1, _imm8, _dest, _srcSize, _destSize, _ext,
|
2009-08-18 03:15:18 +02:00
|
|
|
%(op_class)s)
|
|
|
|
{
|
|
|
|
buildMe();
|
|
|
|
}
|
|
|
|
}};
|
|
|
|
|
|
|
|
let {{
|
|
|
|
# Make these empty strings so that concatenating onto
|
|
|
|
# them will always work.
|
|
|
|
header_output = ""
|
|
|
|
decoder_output = ""
|
|
|
|
exec_output = ""
|
|
|
|
|
|
|
|
immTemplates = (
|
|
|
|
MediaOpImmDeclare,
|
|
|
|
MediaOpImmConstructor,
|
|
|
|
MediaOpExecute)
|
|
|
|
|
|
|
|
regTemplates = (
|
|
|
|
MediaOpRegDeclare,
|
|
|
|
MediaOpRegConstructor,
|
|
|
|
MediaOpExecute)
|
|
|
|
|
|
|
|
class MediaOpMeta(type):
|
|
|
|
def buildCppClasses(self, name, Name, suffix, code):
|
|
|
|
|
|
|
|
# Globals to stick the output in
|
|
|
|
global header_output
|
|
|
|
global decoder_output
|
|
|
|
global exec_output
|
|
|
|
|
|
|
|
# If op2 is used anywhere, make register and immediate versions
|
|
|
|
# of this code.
|
|
|
|
matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?")
|
|
|
|
match = matcher.search(code)
|
|
|
|
if match:
|
|
|
|
typeQual = ""
|
|
|
|
if match.group("typeQual"):
|
|
|
|
typeQual = match.group("typeQual")
|
|
|
|
src2_name = "%spsrc2%s" % (match.group("prefix"), typeQual)
|
|
|
|
self.buildCppClasses(name, Name, suffix,
|
|
|
|
matcher.sub(src2_name, code))
|
|
|
|
self.buildCppClasses(name + "i", Name, suffix + "Imm",
|
|
|
|
matcher.sub("imm8", code))
|
|
|
|
return
|
|
|
|
|
|
|
|
base = "X86ISA::MediaOp"
|
|
|
|
|
|
|
|
# If imm8 shows up in the code, use the immediate templates, if
|
|
|
|
# not, hopefully the register ones will be correct.
|
|
|
|
matcher = re.compile("(?<!\w)imm8(?!\w)")
|
|
|
|
if matcher.search(code):
|
|
|
|
base += "Imm"
|
|
|
|
templates = immTemplates
|
|
|
|
else:
|
|
|
|
base += "Reg"
|
|
|
|
templates = regTemplates
|
|
|
|
|
|
|
|
# Get everything ready for the substitution
|
|
|
|
iop = InstObjParams(name, Name + suffix, base, {"code" : code})
|
|
|
|
|
|
|
|
# Generate the actual code (finally!)
|
|
|
|
header_output += templates[0].subst(iop)
|
|
|
|
decoder_output += templates[1].subst(iop)
|
|
|
|
exec_output += templates[2].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(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict)
|
|
|
|
if not abstract:
|
|
|
|
cls.className = Name
|
|
|
|
cls.base_mnemonic = name
|
|
|
|
code = cls.code
|
|
|
|
|
|
|
|
# Set up the C++ classes
|
|
|
|
mcls.buildCppClasses(cls, name, Name, "", code)
|
|
|
|
|
|
|
|
# Hook into the microassembler dict
|
|
|
|
global microopClasses
|
|
|
|
microopClasses[name] = cls
|
|
|
|
|
|
|
|
# If op2 is used anywhere, make register and immediate versions
|
|
|
|
# of this code.
|
|
|
|
matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
|
|
|
|
if matcher.search(code):
|
|
|
|
microopClasses[name + 'i'] = cls
|
|
|
|
return cls
|
|
|
|
|
|
|
|
|
|
|
|
class MediaOp(X86Microop):
|
|
|
|
__metaclass__ = MediaOpMeta
|
|
|
|
# This class itself doesn't act as a microop
|
|
|
|
abstract = True
|
|
|
|
|
|
|
|
def __init__(self, dest, src1, op2,
|
2009-08-18 03:27:44 +02:00
|
|
|
size = None, destSize = None, srcSize = None, ext = None):
|
2009-08-18 03:15:18 +02:00
|
|
|
self.dest = dest
|
|
|
|
self.src1 = src1
|
|
|
|
self.op2 = op2
|
|
|
|
if size is not None:
|
|
|
|
self.srcSize = size
|
|
|
|
self.destSize = size
|
|
|
|
if srcSize is not None:
|
|
|
|
self.srcSize = srcSize
|
|
|
|
if destSize is not None:
|
|
|
|
self.destSize = destSize
|
|
|
|
if self.srcSize is None:
|
|
|
|
raise Exception, "Source size not set."
|
|
|
|
if self.destSize is None:
|
|
|
|
raise Exception, "Dest size not set."
|
2009-08-18 03:27:44 +02:00
|
|
|
if ext is None:
|
|
|
|
self.ext = 0
|
2009-08-18 03:15:18 +02:00
|
|
|
else:
|
2009-08-18 03:27:44 +02:00
|
|
|
self.ext = ext
|
2009-08-18 03:15:18 +02:00
|
|
|
|
|
|
|
def getAllocator(self, *microFlags):
|
|
|
|
className = self.className
|
|
|
|
if self.mnemonic == self.base_mnemonic + 'i':
|
|
|
|
className += "Imm"
|
|
|
|
allocator = '''new %(class_name)s(machInst, macrocodeBlock
|
|
|
|
%(flags)s, %(src1)s, %(op2)s, %(dest)s,
|
2009-08-18 03:27:44 +02:00
|
|
|
%(srcSize)s, %(destSize)s, %(ext)s)''' % {
|
2009-08-18 03:15:18 +02:00
|
|
|
"class_name" : className,
|
|
|
|
"flags" : self.microFlagsText(microFlags),
|
|
|
|
"src1" : self.src1, "op2" : self.op2,
|
|
|
|
"dest" : self.dest,
|
|
|
|
"srcSize" : self.srcSize,
|
|
|
|
"destSize" : self.destSize,
|
2009-08-18 03:27:44 +02:00
|
|
|
"ext" : self.ext}
|
2009-08-18 03:15:18 +02:00
|
|
|
return allocator
|
|
|
|
|
|
|
|
class Mov2int(MediaOp):
|
|
|
|
def __init__(self, dest, src, \
|
2009-08-18 03:27:44 +02:00
|
|
|
size = None, destSize = None, srcSize = None, ext = None):
|
2009-08-18 03:15:18 +02:00
|
|
|
super(Mov2int, self).__init__(dest, src,\
|
2009-08-18 03:27:44 +02:00
|
|
|
"InstRegIndex(0)", size, destSize, srcSize, ext)
|
2009-08-18 03:15:18 +02:00
|
|
|
code = '''
|
|
|
|
uint64_t fpSrcReg1 = bits(FpSrcReg1.uqw, srcSize * 8 - 1, 0);
|
|
|
|
DestReg = merge(DestReg, fpSrcReg1, destSize);
|
|
|
|
'''
|
|
|
|
|
|
|
|
class Mov2fp(MediaOp):
|
|
|
|
def __init__(self, dest, src, \
|
2009-08-18 03:27:44 +02:00
|
|
|
size = None, destSize = None, srcSize = None, ext = None):
|
2009-08-18 03:15:18 +02:00
|
|
|
super(Mov2fp, self).__init__(dest, src,\
|
2009-08-18 03:27:44 +02:00
|
|
|
"InstRegIndex(0)", size, destSize, srcSize, ext)
|
2009-08-18 03:15:18 +02:00
|
|
|
code = '''
|
|
|
|
uint64_t srcReg1 = pick(SrcReg1, 0, srcSize);
|
|
|
|
FpDestReg.uqw =
|
|
|
|
insertBits(FpDestReg.uqw, destSize * 8 - 1, 0, srcReg1);
|
|
|
|
'''
|
2009-08-18 03:15:39 +02:00
|
|
|
|
|
|
|
class Unpack(MediaOp):
|
|
|
|
code = '''
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = destSize;
|
|
|
|
int items = (sizeof(FloatRegBits) / size) / 2;
|
2009-08-18 03:27:44 +02:00
|
|
|
int offset = ext ? items : 0;
|
2009-08-18 03:15:39 +02:00
|
|
|
uint64_t result = 0;
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
uint64_t pickedLow =
|
|
|
|
bits(FpSrcReg1.uqw, (i + offset + 1) * 8 * size - 1,
|
|
|
|
(i + offset) * 8 * size);
|
|
|
|
result = insertBits(result,
|
|
|
|
(2 * i + 1) * 8 * size - 1,
|
|
|
|
(2 * i + 0) * 8 * size,
|
|
|
|
pickedLow);
|
|
|
|
uint64_t pickedHigh =
|
|
|
|
bits(FpSrcReg2.uqw, (i + offset + 1) * 8 * size - 1,
|
|
|
|
(i + offset) * 8 * size);
|
|
|
|
result = insertBits(result,
|
|
|
|
(2 * i + 2) * 8 * size - 1,
|
|
|
|
(2 * i + 1) * 8 * size,
|
|
|
|
pickedHigh);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 03:22:33 +02:00
|
|
|
|
2009-08-18 03:27:54 +02:00
|
|
|
class Pack(MediaOp):
|
|
|
|
code = '''
|
|
|
|
assert(srcSize == destSize * 2);
|
|
|
|
int items = (sizeof(FloatRegBits) / destSize);
|
|
|
|
int destBits = destSize * 8;
|
|
|
|
int srcBits = srcSize * 8;
|
|
|
|
uint64_t result = 0;
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < items / 2; i++) {
|
|
|
|
uint64_t picked =
|
|
|
|
bits(FpSrcReg1.uqw, (i + 1) * srcBits - 1,
|
|
|
|
(i + 0) * srcBits);
|
|
|
|
unsigned signBit = bits(picked, srcBits - 1);
|
|
|
|
uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
|
|
|
|
|
|
|
|
// Handle saturation.
|
|
|
|
if (signBit) {
|
|
|
|
if (overflow != mask(destBits - srcBits + 1)) {
|
|
|
|
if (ext & 0x1)
|
|
|
|
picked = (1 << (destBits - 1));
|
|
|
|
else
|
|
|
|
picked = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (overflow != 0) {
|
|
|
|
if (ext & 0x1)
|
|
|
|
picked = mask(destBits - 1);
|
|
|
|
else
|
|
|
|
picked = mask(destBits);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result = insertBits(result,
|
|
|
|
(i + 1) * destBits - 1,
|
|
|
|
(i + 0) * destBits,
|
|
|
|
picked);
|
|
|
|
}
|
|
|
|
for (;i < items; i++) {
|
|
|
|
uint64_t picked =
|
|
|
|
bits(FpSrcReg2.uqw, (i - items + 1) * srcBits - 1,
|
|
|
|
(i - items + 0) * srcBits);
|
|
|
|
unsigned signBit = bits(picked, srcBits - 1);
|
|
|
|
uint64_t overflow = bits(picked, srcBits - 1, destBits - 1);
|
|
|
|
|
|
|
|
// Handle saturation.
|
|
|
|
if (signBit) {
|
|
|
|
if (overflow != mask(destBits - srcBits + 1)) {
|
|
|
|
if (ext & 0x1)
|
|
|
|
picked = (1 << (destBits - 1));
|
|
|
|
else
|
|
|
|
picked = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (overflow != 0) {
|
|
|
|
if (ext & 0x1)
|
|
|
|
picked = mask(destBits - 1);
|
|
|
|
else
|
|
|
|
picked = mask(destBits);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result = insertBits(result,
|
|
|
|
(i + 1) * destBits - 1,
|
|
|
|
(i + 0) * destBits,
|
|
|
|
picked);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
|
|
|
|
2009-08-18 03:22:33 +02:00
|
|
|
class Mxor(MediaOp):
|
|
|
|
def __init__(self, dest, src1, src2):
|
|
|
|
super(Mxor, self).__init__(dest, src1, src2, 1)
|
|
|
|
code = '''
|
|
|
|
FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;
|
|
|
|
'''
|
2009-08-18 03:23:30 +02:00
|
|
|
|
|
|
|
class Mor(MediaOp):
|
|
|
|
def __init__(self, dest, src1, src2):
|
|
|
|
super(Mor, self).__init__(dest, src1, src2, 1)
|
|
|
|
code = '''
|
|
|
|
FpDestReg.uqw = FpSrcReg1.uqw | FpSrcReg2.uqw;
|
|
|
|
'''
|
2009-08-18 03:24:16 +02:00
|
|
|
|
|
|
|
class Mand(MediaOp):
|
|
|
|
def __init__(self, dest, src1, src2):
|
|
|
|
super(Mand, self).__init__(dest, src1, src2, 1)
|
|
|
|
code = '''
|
|
|
|
FpDestReg.uqw = FpSrcReg1.uqw & FpSrcReg2.uqw;
|
|
|
|
'''
|
2009-08-18 03:24:58 +02:00
|
|
|
|
|
|
|
class Mandn(MediaOp):
|
|
|
|
def __init__(self, dest, src1, src2):
|
|
|
|
super(Mandn, self).__init__(dest, src1, src2, 1)
|
|
|
|
code = '''
|
|
|
|
FpDestReg.uqw = ~FpSrcReg1.uqw & FpSrcReg2.uqw;
|
|
|
|
'''
|
2009-08-18 03:32:09 +02:00
|
|
|
|
|
|
|
class Mminf(MediaOp):
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
double arg1, arg2;
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
|
|
|
|
if (size == 4) {
|
|
|
|
floatInt fi;
|
|
|
|
fi.i = arg1Bits;
|
|
|
|
arg1 = fi.f;
|
|
|
|
fi.i = arg2Bits;
|
|
|
|
arg2 = fi.f;
|
|
|
|
} else {
|
|
|
|
doubleInt di;
|
|
|
|
di.i = arg1Bits;
|
|
|
|
arg1 = di.d;
|
|
|
|
di.i = arg2Bits;
|
|
|
|
arg2 = di.d;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (arg1 < arg2) {
|
|
|
|
result = insertBits(result, hiIndex, loIndex, arg1Bits);
|
|
|
|
} else {
|
|
|
|
result = insertBits(result, hiIndex, loIndex, arg2Bits);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 03:33:25 +02:00
|
|
|
|
|
|
|
class Mmaxf(MediaOp):
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
double arg1, arg2;
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
|
|
|
|
if (size == 4) {
|
|
|
|
floatInt fi;
|
|
|
|
fi.i = arg1Bits;
|
|
|
|
arg1 = fi.f;
|
|
|
|
fi.i = arg2Bits;
|
|
|
|
arg2 = fi.f;
|
|
|
|
} else {
|
|
|
|
doubleInt di;
|
|
|
|
di.i = arg1Bits;
|
|
|
|
arg1 = di.d;
|
|
|
|
di.i = arg2Bits;
|
|
|
|
arg2 = di.d;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (arg1 > arg2) {
|
|
|
|
result = insertBits(result, hiIndex, loIndex, arg1Bits);
|
|
|
|
} else {
|
|
|
|
result = insertBits(result, hiIndex, loIndex, arg2Bits);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 03:34:16 +02:00
|
|
|
|
2009-08-18 05:04:02 +02:00
|
|
|
class Mmini(MediaOp):
|
|
|
|
code = '''
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
int64_t arg1 = arg1Bits |
|
|
|
|
(0 - (arg1Bits & (1 << (sizeBits - 1))));
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
int64_t arg2 = arg2Bits |
|
|
|
|
(0 - (arg2Bits & (1 << (sizeBits - 1))));
|
|
|
|
uint64_t resBits;
|
|
|
|
|
|
|
|
if (ext & 0x2) {
|
|
|
|
if (arg1 < arg2) {
|
|
|
|
resBits = arg1Bits;
|
|
|
|
} else {
|
|
|
|
resBits = arg2Bits;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (arg1Bits < arg2Bits) {
|
|
|
|
resBits = arg1Bits;
|
|
|
|
} else {
|
|
|
|
resBits = arg2Bits;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result = insertBits(result, hiIndex, loIndex, resBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
|
|
|
|
2009-08-18 03:34:16 +02:00
|
|
|
class Msqrt(MediaOp):
|
|
|
|
def __init__(self, dest, src, \
|
|
|
|
size = None, destSize = None, srcSize = None, ext = None):
|
|
|
|
super(Msqrt, self).__init__(dest, src,\
|
|
|
|
"InstRegIndex(0)", size, destSize, srcSize, ext)
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t argBits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
|
|
|
|
if (size == 4) {
|
|
|
|
floatInt fi;
|
|
|
|
fi.i = argBits;
|
|
|
|
fi.f = sqrt(fi.f);
|
|
|
|
argBits = fi.i;
|
|
|
|
} else {
|
|
|
|
doubleInt di;
|
|
|
|
di.i = argBits;
|
|
|
|
di.d = sqrt(di.d);
|
|
|
|
argBits = di.i;
|
|
|
|
}
|
|
|
|
result = insertBits(result, hiIndex, loIndex, argBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 03:35:04 +02:00
|
|
|
|
|
|
|
class Maddf(MediaOp):
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t resBits;
|
|
|
|
|
|
|
|
if (size == 4) {
|
|
|
|
floatInt arg1, arg2, res;
|
|
|
|
arg1.i = arg1Bits;
|
|
|
|
arg2.i = arg2Bits;
|
|
|
|
res.f = arg1.f + arg2.f;
|
|
|
|
resBits = res.i;
|
|
|
|
} else {
|
|
|
|
doubleInt arg1, arg2, res;
|
|
|
|
arg1.i = arg1Bits;
|
|
|
|
arg2.i = arg2Bits;
|
|
|
|
res.d = arg1.d + arg2.d;
|
|
|
|
resBits = res.i;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = insertBits(result, hiIndex, loIndex, resBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 03:36:18 +02:00
|
|
|
|
|
|
|
class Msubf(MediaOp):
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t resBits;
|
|
|
|
|
|
|
|
if (size == 4) {
|
|
|
|
floatInt arg1, arg2, res;
|
|
|
|
arg1.i = arg1Bits;
|
|
|
|
arg2.i = arg2Bits;
|
|
|
|
res.f = arg1.f - arg2.f;
|
|
|
|
resBits = res.i;
|
|
|
|
} else {
|
|
|
|
doubleInt arg1, arg2, res;
|
|
|
|
arg1.i = arg1Bits;
|
|
|
|
arg2.i = arg2Bits;
|
|
|
|
res.d = arg1.d - arg2.d;
|
|
|
|
resBits = res.i;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = insertBits(result, hiIndex, loIndex, resBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 03:38:51 +02:00
|
|
|
|
|
|
|
class Mmulf(MediaOp):
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t resBits;
|
|
|
|
|
|
|
|
if (size == 4) {
|
|
|
|
floatInt arg1, arg2, res;
|
|
|
|
arg1.i = arg1Bits;
|
|
|
|
arg2.i = arg2Bits;
|
|
|
|
res.f = arg1.f * arg2.f;
|
|
|
|
resBits = res.i;
|
|
|
|
} else {
|
|
|
|
doubleInt arg1, arg2, res;
|
|
|
|
arg1.i = arg1Bits;
|
|
|
|
arg2.i = arg2Bits;
|
|
|
|
res.d = arg1.d * arg2.d;
|
|
|
|
resBits = res.i;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = insertBits(result, hiIndex, loIndex, resBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 03:40:38 +02:00
|
|
|
|
|
|
|
class Mdivf(MediaOp):
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t resBits;
|
|
|
|
|
|
|
|
if (size == 4) {
|
|
|
|
floatInt arg1, arg2, res;
|
|
|
|
arg1.i = arg1Bits;
|
|
|
|
arg2.i = arg2Bits;
|
|
|
|
res.f = arg1.f / arg2.f;
|
|
|
|
resBits = res.i;
|
|
|
|
} else {
|
|
|
|
doubleInt arg1, arg2, res;
|
|
|
|
arg1.i = arg1Bits;
|
|
|
|
arg2.i = arg2Bits;
|
|
|
|
res.d = arg1.d / arg2.d;
|
|
|
|
resBits = res.i;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = insertBits(result, hiIndex, loIndex, resBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
2009-08-18 05:04:02 +02:00
|
|
|
'''
|
|
|
|
|
|
|
|
class Maddi(MediaOp):
|
|
|
|
code = '''
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
uint64_t resBits = arg1Bits + arg2Bits;
|
|
|
|
|
|
|
|
if (ext & 0x2) {
|
|
|
|
if (findCarry(sizeBits, resBits, arg1Bits, arg2Bits))
|
|
|
|
resBits = mask(sizeBits);
|
|
|
|
} else if (ext & 0x4) {
|
|
|
|
int arg1Sign = bits(arg1Bits, sizeBits - 1);
|
|
|
|
int arg2Sign = bits(arg2Bits, sizeBits - 1);
|
|
|
|
int resSign = bits(resBits, sizeBits - 1);
|
|
|
|
if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) {
|
|
|
|
if (resSign == 0)
|
|
|
|
resBits = (1 << (sizeBits - 1));
|
|
|
|
else
|
|
|
|
resBits = mask(sizeBits - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result = insertBits(result, hiIndex, loIndex, resBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
2009-08-18 03:40:38 +02:00
|
|
|
'''
|
2009-08-18 03:41:25 +02:00
|
|
|
|
|
|
|
class Cvti2f(MediaOp):
|
|
|
|
def __init__(self, dest, src, \
|
|
|
|
size = None, destSize = None, srcSize = None, ext = None):
|
|
|
|
super(Cvti2f, self).__init__(dest, src,\
|
|
|
|
"InstRegIndex(0)", size, destSize, srcSize, ext)
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(destSize == 4 || destSize == 8);
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int srcSizeBits = srcSize * 8;
|
|
|
|
int destSizeBits = destSize * 8;
|
|
|
|
int items;
|
|
|
|
int srcStart = 0;
|
|
|
|
int destStart = 0;
|
|
|
|
if (srcSize == 2 * destSize) {
|
|
|
|
items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / srcSize;
|
|
|
|
if (ext & 0x2)
|
|
|
|
destStart = destSizeBits * items;
|
|
|
|
} else if (destSize == 2 * srcSize) {
|
|
|
|
items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
|
|
|
|
if (ext & 0x2)
|
|
|
|
srcStart = srcSizeBits * items;
|
|
|
|
} else {
|
|
|
|
items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
|
|
|
|
}
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
|
|
|
|
int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
|
|
|
|
uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
|
|
|
|
int64_t sArg = argBits | (0 - (argBits & (1 << srcHiIndex)));
|
|
|
|
double arg = sArg;
|
|
|
|
|
|
|
|
if (destSize == 4) {
|
|
|
|
floatInt fi;
|
|
|
|
fi.f = arg;
|
|
|
|
argBits = fi.i;
|
|
|
|
} else {
|
|
|
|
doubleInt di;
|
|
|
|
di.d = arg;
|
|
|
|
argBits = di.i;
|
|
|
|
}
|
|
|
|
int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
|
|
|
|
int destLoIndex = destStart + (i + 0) * destSizeBits;
|
|
|
|
result = insertBits(result, destHiIndex, destLoIndex, argBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 05:04:02 +02:00
|
|
|
|
2009-08-18 05:04:02 +02:00
|
|
|
class Cvtf2f(MediaOp):
|
|
|
|
def __init__(self, dest, src, \
|
|
|
|
size = None, destSize = None, srcSize = None, ext = None):
|
|
|
|
super(Cvtf2f, self).__init__(dest, src,\
|
|
|
|
"InstRegIndex(0)", size, destSize, srcSize, ext)
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(destSize == 4 || destSize == 8);
|
|
|
|
assert(srcSize == 4 || srcSize == 8);
|
|
|
|
int srcSizeBits = srcSize * 8;
|
|
|
|
int destSizeBits = destSize * 8;
|
|
|
|
int items;
|
|
|
|
int srcStart = 0;
|
|
|
|
int destStart = 0;
|
|
|
|
if (srcSize == 2 * destSize) {
|
|
|
|
items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / srcSize;
|
|
|
|
if (ext & 0x2)
|
|
|
|
destStart = destSizeBits * items;
|
|
|
|
} else if (destSize == 2 * srcSize) {
|
|
|
|
items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
|
|
|
|
if (ext & 0x2)
|
|
|
|
srcStart = srcSizeBits * items;
|
|
|
|
} else {
|
|
|
|
items = (ext & 0x1) ? 1: sizeof(FloatRegBits) / destSize;
|
|
|
|
}
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1;
|
|
|
|
int srcLoIndex = srcStart + (i + 0) * srcSizeBits;
|
|
|
|
uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex);
|
|
|
|
double arg;
|
|
|
|
|
|
|
|
if (srcSize == 4) {
|
|
|
|
floatInt fi;
|
|
|
|
fi.i = argBits;
|
|
|
|
arg = fi.f;
|
|
|
|
} else {
|
|
|
|
doubleInt di;
|
|
|
|
di.i = argBits;
|
|
|
|
arg = di.d;
|
|
|
|
}
|
|
|
|
if (destSize == 4) {
|
|
|
|
floatInt fi;
|
|
|
|
fi.f = arg;
|
|
|
|
argBits = fi.i;
|
|
|
|
} else {
|
|
|
|
doubleInt di;
|
|
|
|
di.d = arg;
|
|
|
|
argBits = di.i;
|
|
|
|
}
|
|
|
|
int destHiIndex = destStart + (i + 1) * destSizeBits - 1;
|
|
|
|
int destLoIndex = destStart + (i + 0) * destSizeBits;
|
|
|
|
result = insertBits(result, destHiIndex, destLoIndex, argBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
|
|
|
|
2009-08-18 05:04:02 +02:00
|
|
|
class Mcmpi2r(MediaOp):
|
|
|
|
code = '''
|
|
|
|
union floatInt
|
|
|
|
{
|
|
|
|
float f;
|
|
|
|
uint32_t i;
|
|
|
|
};
|
|
|
|
union doubleInt
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
uint64_t i;
|
|
|
|
};
|
|
|
|
|
|
|
|
assert(srcSize == destSize);
|
|
|
|
int size = srcSize;
|
|
|
|
int sizeBits = size * 8;
|
|
|
|
int items = (ext & 0x1) ? 1: (sizeof(FloatRegBits) / size);
|
|
|
|
uint64_t result = FpDestReg.uqw;
|
|
|
|
|
|
|
|
for (int i = 0; i < items; i++) {
|
|
|
|
int hiIndex = (i + 1) * sizeBits - 1;
|
|
|
|
int loIndex = (i + 0) * sizeBits;
|
|
|
|
uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex);
|
|
|
|
int64_t arg1 = arg1Bits |
|
|
|
|
(0 - (arg1Bits & (1 << (sizeBits - 1))));
|
|
|
|
uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex);
|
|
|
|
int64_t arg2 = arg2Bits |
|
|
|
|
(0 - (arg2Bits & (1 << (sizeBits - 1))));
|
|
|
|
|
|
|
|
uint64_t resBits = 0;
|
|
|
|
if ((ext & 0x2) == 0 && arg1 == arg2 ||
|
|
|
|
(ext & 0x2) == 0x2 && arg1 > arg2)
|
|
|
|
resBits = mask(sizeBits);
|
|
|
|
|
|
|
|
result = insertBits(result, hiIndex, loIndex, resBits);
|
|
|
|
}
|
|
|
|
FpDestReg.uqw = result;
|
|
|
|
'''
|
2009-08-18 03:15:18 +02:00
|
|
|
}};
|