mediaop.isa revision 12707
111160Ssteve.reinhardt@amd.com// Copyright (c) 2009 The Regents of The University of Michigan 211160Ssteve.reinhardt@amd.com// Copyright (c) 2015 Advanced Micro Devices, Inc. 311160Ssteve.reinhardt@amd.com// 46516Sgblack@eecs.umich.edu// All rights reserved. 56516Sgblack@eecs.umich.edu// 66516Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 76516Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 86516Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 96516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 106516Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 116516Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 126516Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 136516Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 146516Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 156516Sgblack@eecs.umich.edu// this software without specific prior written permission. 166516Sgblack@eecs.umich.edu// 176516Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186516Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196516Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206516Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216516Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226516Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236516Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246516Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256516Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266516Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276516Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286516Sgblack@eecs.umich.edu// 296516Sgblack@eecs.umich.edu// Authors: Gabe Black 306516Sgblack@eecs.umich.edu 316516Sgblack@eecs.umich.edudef template MediaOpExecute {{ 3212234Sgabeblack@google.com Fault %(class_name)s::execute(ExecContext *xc, 336516Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 346516Sgblack@eecs.umich.edu { 356516Sgblack@eecs.umich.edu Fault fault = NoFault; 366516Sgblack@eecs.umich.edu 376516Sgblack@eecs.umich.edu %(op_decl)s; 386516Sgblack@eecs.umich.edu %(op_rd)s; 396516Sgblack@eecs.umich.edu 406516Sgblack@eecs.umich.edu %(code)s; 416516Sgblack@eecs.umich.edu 426516Sgblack@eecs.umich.edu //Write the resulting state to the execution context 436516Sgblack@eecs.umich.edu if(fault == NoFault) 446516Sgblack@eecs.umich.edu { 456516Sgblack@eecs.umich.edu %(op_wb)s; 466516Sgblack@eecs.umich.edu } 476516Sgblack@eecs.umich.edu return fault; 486516Sgblack@eecs.umich.edu } 496516Sgblack@eecs.umich.edu}}; 506516Sgblack@eecs.umich.edu 516516Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{ 526516Sgblack@eecs.umich.edu class %(class_name)s : public %(base_class)s 536516Sgblack@eecs.umich.edu { 546516Sgblack@eecs.umich.edu public: 556516Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst _machInst, 567620Sgblack@eecs.umich.edu const char * instMnem, uint64_t setFlags, 576516Sgblack@eecs.umich.edu InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 586545Sgblack@eecs.umich.edu uint8_t _srcSize, uint8_t _destSize, uint16_t _ext); 596516Sgblack@eecs.umich.edu 6012236Sgabeblack@google.com Fault execute(ExecContext *, Trace::InstRecord *) const; 616516Sgblack@eecs.umich.edu }; 626516Sgblack@eecs.umich.edu}}; 636516Sgblack@eecs.umich.edu 646516Sgblack@eecs.umich.edudef template MediaOpImmDeclare {{ 656516Sgblack@eecs.umich.edu 666516Sgblack@eecs.umich.edu class %(class_name)s : public %(base_class)s 676516Sgblack@eecs.umich.edu { 686516Sgblack@eecs.umich.edu public: 696516Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst _machInst, 707620Sgblack@eecs.umich.edu const char * instMnem, uint64_t setFlags, 716516Sgblack@eecs.umich.edu InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, 726545Sgblack@eecs.umich.edu uint8_t _srcSize, uint8_t _destSize, uint16_t _ext); 736516Sgblack@eecs.umich.edu 7412236Sgabeblack@google.com Fault execute(ExecContext *, Trace::InstRecord *) const; 756516Sgblack@eecs.umich.edu }; 766516Sgblack@eecs.umich.edu}}; 776516Sgblack@eecs.umich.edu 786516Sgblack@eecs.umich.edudef template MediaOpRegConstructor {{ 7910184SCurtis.Dunham@arm.com %(class_name)s::%(class_name)s( 807620Sgblack@eecs.umich.edu ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 816516Sgblack@eecs.umich.edu InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 826545Sgblack@eecs.umich.edu uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) : 837620Sgblack@eecs.umich.edu %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 846545Sgblack@eecs.umich.edu _src1, _src2, _dest, _srcSize, _destSize, _ext, 856516Sgblack@eecs.umich.edu %(op_class)s) 866516Sgblack@eecs.umich.edu { 877626Sgblack@eecs.umich.edu %(constructor)s; 886516Sgblack@eecs.umich.edu } 896516Sgblack@eecs.umich.edu}}; 906516Sgblack@eecs.umich.edu 916516Sgblack@eecs.umich.edudef template MediaOpImmConstructor {{ 9210184SCurtis.Dunham@arm.com %(class_name)s::%(class_name)s( 937620Sgblack@eecs.umich.edu ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 946516Sgblack@eecs.umich.edu InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, 956545Sgblack@eecs.umich.edu uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) : 967620Sgblack@eecs.umich.edu %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 976545Sgblack@eecs.umich.edu _src1, _imm8, _dest, _srcSize, _destSize, _ext, 986516Sgblack@eecs.umich.edu %(op_class)s) 996516Sgblack@eecs.umich.edu { 1007626Sgblack@eecs.umich.edu %(constructor)s; 1016516Sgblack@eecs.umich.edu } 1026516Sgblack@eecs.umich.edu}}; 1036516Sgblack@eecs.umich.edu 1046516Sgblack@eecs.umich.edulet {{ 1056516Sgblack@eecs.umich.edu # Make these empty strings so that concatenating onto 1066516Sgblack@eecs.umich.edu # them will always work. 1076516Sgblack@eecs.umich.edu header_output = "" 1086516Sgblack@eecs.umich.edu decoder_output = "" 1096516Sgblack@eecs.umich.edu exec_output = "" 1106516Sgblack@eecs.umich.edu 1116516Sgblack@eecs.umich.edu immTemplates = ( 1126516Sgblack@eecs.umich.edu MediaOpImmDeclare, 1136516Sgblack@eecs.umich.edu MediaOpImmConstructor, 1146516Sgblack@eecs.umich.edu MediaOpExecute) 1156516Sgblack@eecs.umich.edu 1166516Sgblack@eecs.umich.edu regTemplates = ( 1176516Sgblack@eecs.umich.edu MediaOpRegDeclare, 1186516Sgblack@eecs.umich.edu MediaOpRegConstructor, 1196516Sgblack@eecs.umich.edu MediaOpExecute) 1206516Sgblack@eecs.umich.edu 1216516Sgblack@eecs.umich.edu class MediaOpMeta(type): 1226516Sgblack@eecs.umich.edu def buildCppClasses(self, name, Name, suffix, code): 1236516Sgblack@eecs.umich.edu 1246516Sgblack@eecs.umich.edu # Globals to stick the output in 1256516Sgblack@eecs.umich.edu global header_output 1266516Sgblack@eecs.umich.edu global decoder_output 1276516Sgblack@eecs.umich.edu global exec_output 1286516Sgblack@eecs.umich.edu 1296516Sgblack@eecs.umich.edu # If op2 is used anywhere, make register and immediate versions 1306516Sgblack@eecs.umich.edu # of this code. 1318588Sgblack@eecs.umich.edu matcher = re.compile(r"(?<!\w)(?P<prefix>s?)op2(?P<typeQual>_[^\W_]+)?") 1326516Sgblack@eecs.umich.edu match = matcher.search(code) 1336516Sgblack@eecs.umich.edu if match: 1346516Sgblack@eecs.umich.edu typeQual = "" 1356516Sgblack@eecs.umich.edu if match.group("typeQual"): 1366516Sgblack@eecs.umich.edu typeQual = match.group("typeQual") 1376583Sgblack@eecs.umich.edu src2_name = "%sFpSrcReg2%s" % (match.group("prefix"), typeQual) 1386516Sgblack@eecs.umich.edu self.buildCppClasses(name, Name, suffix, 1396516Sgblack@eecs.umich.edu matcher.sub(src2_name, code)) 1406516Sgblack@eecs.umich.edu self.buildCppClasses(name + "i", Name, suffix + "Imm", 1416516Sgblack@eecs.umich.edu matcher.sub("imm8", code)) 1426516Sgblack@eecs.umich.edu return 1436516Sgblack@eecs.umich.edu 1446516Sgblack@eecs.umich.edu base = "X86ISA::MediaOp" 1456516Sgblack@eecs.umich.edu 1466516Sgblack@eecs.umich.edu # If imm8 shows up in the code, use the immediate templates, if 1476516Sgblack@eecs.umich.edu # not, hopefully the register ones will be correct. 1486516Sgblack@eecs.umich.edu matcher = re.compile("(?<!\w)imm8(?!\w)") 1496516Sgblack@eecs.umich.edu if matcher.search(code): 1506516Sgblack@eecs.umich.edu base += "Imm" 1516516Sgblack@eecs.umich.edu templates = immTemplates 1526516Sgblack@eecs.umich.edu else: 1536516Sgblack@eecs.umich.edu base += "Reg" 1546516Sgblack@eecs.umich.edu templates = regTemplates 1556516Sgblack@eecs.umich.edu 1566516Sgblack@eecs.umich.edu # Get everything ready for the substitution 15712707Sgabeblack@google.com opt_args = [] 15812707Sgabeblack@google.com if self.op_class: 15912707Sgabeblack@google.com opt_args.append(self.op_class) 16012707Sgabeblack@google.com iop = InstObjParams(name, Name + suffix, base, {"code" : code}, 16112707Sgabeblack@google.com opt_args) 1626516Sgblack@eecs.umich.edu 1636516Sgblack@eecs.umich.edu # Generate the actual code (finally!) 1646516Sgblack@eecs.umich.edu header_output += templates[0].subst(iop) 1656516Sgblack@eecs.umich.edu decoder_output += templates[1].subst(iop) 1666516Sgblack@eecs.umich.edu exec_output += templates[2].subst(iop) 1676516Sgblack@eecs.umich.edu 1686516Sgblack@eecs.umich.edu 1696516Sgblack@eecs.umich.edu def __new__(mcls, Name, bases, dict): 1706516Sgblack@eecs.umich.edu abstract = False 1716516Sgblack@eecs.umich.edu name = Name.lower() 1726516Sgblack@eecs.umich.edu if "abstract" in dict: 1736516Sgblack@eecs.umich.edu abstract = dict['abstract'] 1746516Sgblack@eecs.umich.edu del dict['abstract'] 17512707Sgabeblack@google.com if not "op_class" in dict: 17612707Sgabeblack@google.com dict["op_class"] = None 1776516Sgblack@eecs.umich.edu 1786516Sgblack@eecs.umich.edu cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict) 1796516Sgblack@eecs.umich.edu if not abstract: 1806516Sgblack@eecs.umich.edu cls.className = Name 1816516Sgblack@eecs.umich.edu cls.base_mnemonic = name 1826516Sgblack@eecs.umich.edu code = cls.code 1836516Sgblack@eecs.umich.edu 1846516Sgblack@eecs.umich.edu # Set up the C++ classes 1856516Sgblack@eecs.umich.edu mcls.buildCppClasses(cls, name, Name, "", code) 1866516Sgblack@eecs.umich.edu 1876516Sgblack@eecs.umich.edu # Hook into the microassembler dict 1886516Sgblack@eecs.umich.edu global microopClasses 1896516Sgblack@eecs.umich.edu microopClasses[name] = cls 1906516Sgblack@eecs.umich.edu 1916516Sgblack@eecs.umich.edu # If op2 is used anywhere, make register and immediate versions 1926516Sgblack@eecs.umich.edu # of this code. 1938588Sgblack@eecs.umich.edu matcher = re.compile(r"op2(?P<typeQual>_[^\W_]+)?") 1946516Sgblack@eecs.umich.edu if matcher.search(code): 1956516Sgblack@eecs.umich.edu microopClasses[name + 'i'] = cls 1966516Sgblack@eecs.umich.edu return cls 1976516Sgblack@eecs.umich.edu 1986516Sgblack@eecs.umich.edu 1996516Sgblack@eecs.umich.edu class MediaOp(X86Microop): 2006516Sgblack@eecs.umich.edu __metaclass__ = MediaOpMeta 2016516Sgblack@eecs.umich.edu # This class itself doesn't act as a microop 2026516Sgblack@eecs.umich.edu abstract = True 2036516Sgblack@eecs.umich.edu 2046516Sgblack@eecs.umich.edu def __init__(self, dest, src1, op2, 2056545Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 2066516Sgblack@eecs.umich.edu self.dest = dest 2076516Sgblack@eecs.umich.edu self.src1 = src1 2086516Sgblack@eecs.umich.edu self.op2 = op2 2096516Sgblack@eecs.umich.edu if size is not None: 2106516Sgblack@eecs.umich.edu self.srcSize = size 2116516Sgblack@eecs.umich.edu self.destSize = size 2126516Sgblack@eecs.umich.edu if srcSize is not None: 2136516Sgblack@eecs.umich.edu self.srcSize = srcSize 2146516Sgblack@eecs.umich.edu if destSize is not None: 2156516Sgblack@eecs.umich.edu self.destSize = destSize 2166516Sgblack@eecs.umich.edu if self.srcSize is None: 2176516Sgblack@eecs.umich.edu raise Exception, "Source size not set." 2186516Sgblack@eecs.umich.edu if self.destSize is None: 2196516Sgblack@eecs.umich.edu raise Exception, "Dest size not set." 2206545Sgblack@eecs.umich.edu if ext is None: 2216545Sgblack@eecs.umich.edu self.ext = 0 2226516Sgblack@eecs.umich.edu else: 22311320Ssteve.reinhardt@amd.com self.ext = ext 2246516Sgblack@eecs.umich.edu 2257620Sgblack@eecs.umich.edu def getAllocator(self, microFlags): 2266516Sgblack@eecs.umich.edu className = self.className 2276516Sgblack@eecs.umich.edu if self.mnemonic == self.base_mnemonic + 'i': 2286516Sgblack@eecs.umich.edu className += "Imm" 2297620Sgblack@eecs.umich.edu allocator = '''new %(class_name)s(machInst, macrocodeBlock, 2306516Sgblack@eecs.umich.edu %(flags)s, %(src1)s, %(op2)s, %(dest)s, 2316545Sgblack@eecs.umich.edu %(srcSize)s, %(destSize)s, %(ext)s)''' % { 2326516Sgblack@eecs.umich.edu "class_name" : className, 2336516Sgblack@eecs.umich.edu "flags" : self.microFlagsText(microFlags), 2346516Sgblack@eecs.umich.edu "src1" : self.src1, "op2" : self.op2, 2356516Sgblack@eecs.umich.edu "dest" : self.dest, 2366516Sgblack@eecs.umich.edu "srcSize" : self.srcSize, 2376516Sgblack@eecs.umich.edu "destSize" : self.destSize, 2386545Sgblack@eecs.umich.edu "ext" : self.ext} 2396516Sgblack@eecs.umich.edu return allocator 2406516Sgblack@eecs.umich.edu 2416516Sgblack@eecs.umich.edu class Mov2int(MediaOp): 2426589Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2 = 0, \ 2436545Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 2446589Sgblack@eecs.umich.edu super(Mov2int, self).__init__(dest, src1,\ 2456589Sgblack@eecs.umich.edu src2, size, destSize, srcSize, ext) 24612707Sgabeblack@google.com op_class = 'SimdMiscOp' 2476516Sgblack@eecs.umich.edu code = ''' 2486589Sgblack@eecs.umich.edu int items = sizeof(FloatRegBits) / srcSize; 2496589Sgblack@eecs.umich.edu int offset = imm8; 2506589Sgblack@eecs.umich.edu if (bits(src1, 0) && (ext & 0x1)) 2516589Sgblack@eecs.umich.edu offset -= items; 2526589Sgblack@eecs.umich.edu if (offset >= 0 && offset < items) { 2536589Sgblack@eecs.umich.edu uint64_t fpSrcReg1 = 2548588Sgblack@eecs.umich.edu bits(FpSrcReg1_uqw, 2556589Sgblack@eecs.umich.edu (offset + 1) * srcSize * 8 - 1, 2566589Sgblack@eecs.umich.edu (offset + 0) * srcSize * 8); 2576589Sgblack@eecs.umich.edu DestReg = merge(0, fpSrcReg1, destSize); 2586589Sgblack@eecs.umich.edu } else { 2596589Sgblack@eecs.umich.edu DestReg = DestReg; 2606589Sgblack@eecs.umich.edu } 2616516Sgblack@eecs.umich.edu ''' 2626516Sgblack@eecs.umich.edu 2636516Sgblack@eecs.umich.edu class Mov2fp(MediaOp): 2646589Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2 = 0, \ 2656545Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 2666589Sgblack@eecs.umich.edu super(Mov2fp, self).__init__(dest, src1,\ 2676589Sgblack@eecs.umich.edu src2, size, destSize, srcSize, ext) 26812707Sgabeblack@google.com op_class = 'SimdMiscOp' 2696516Sgblack@eecs.umich.edu code = ''' 2706589Sgblack@eecs.umich.edu int items = sizeof(FloatRegBits) / destSize; 2716589Sgblack@eecs.umich.edu int offset = imm8; 2726589Sgblack@eecs.umich.edu if (bits(dest, 0) && (ext & 0x1)) 2736589Sgblack@eecs.umich.edu offset -= items; 2746589Sgblack@eecs.umich.edu if (offset >= 0 && offset < items) { 2756589Sgblack@eecs.umich.edu uint64_t srcReg1 = pick(SrcReg1, 0, srcSize); 2768588Sgblack@eecs.umich.edu FpDestReg_uqw = 2778588Sgblack@eecs.umich.edu insertBits(FpDestReg_uqw, 2786589Sgblack@eecs.umich.edu (offset + 1) * destSize * 8 - 1, 2796589Sgblack@eecs.umich.edu (offset + 0) * destSize * 8, srcReg1); 2806589Sgblack@eecs.umich.edu } else { 2818588Sgblack@eecs.umich.edu FpDestReg_uqw = FpDestReg_uqw; 2826589Sgblack@eecs.umich.edu } 2836516Sgblack@eecs.umich.edu ''' 2846521Sgblack@eecs.umich.edu 2856592Sgblack@eecs.umich.edu class Movsign(MediaOp): 2866592Sgblack@eecs.umich.edu def __init__(self, dest, src, \ 2876592Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 2886592Sgblack@eecs.umich.edu super(Movsign, self).__init__(dest, src,\ 2896592Sgblack@eecs.umich.edu "InstRegIndex(0)", size, destSize, srcSize, ext) 29012707Sgabeblack@google.com op_class = 'SimdMiscOp' 2916592Sgblack@eecs.umich.edu code = ''' 2926592Sgblack@eecs.umich.edu int items = sizeof(FloatRegBits) / srcSize; 2936592Sgblack@eecs.umich.edu uint64_t result = 0; 2946592Sgblack@eecs.umich.edu int offset = (ext & 0x1) ? items : 0; 2956592Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 2966592Sgblack@eecs.umich.edu uint64_t picked = 2978588Sgblack@eecs.umich.edu bits(FpSrcReg1_uqw, (i + 1) * 8 * srcSize - 1); 2986592Sgblack@eecs.umich.edu result = insertBits(result, i + offset, i + offset, picked); 2996592Sgblack@eecs.umich.edu } 3006592Sgblack@eecs.umich.edu DestReg = DestReg | result; 3016592Sgblack@eecs.umich.edu ''' 3026592Sgblack@eecs.umich.edu 3036594Sgblack@eecs.umich.edu class Maskmov(MediaOp): 30412707Sgabeblack@google.com op_class = 'SimdMiscOp' 3056594Sgblack@eecs.umich.edu code = ''' 3066594Sgblack@eecs.umich.edu assert(srcSize == destSize); 3076594Sgblack@eecs.umich.edu int size = srcSize; 3086594Sgblack@eecs.umich.edu int sizeBits = size * 8; 3096799Sgblack@eecs.umich.edu int items = numItems(size); 3108588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 3116594Sgblack@eecs.umich.edu 3126594Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 3136594Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 3146594Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 3158588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 3168588Sgblack@eecs.umich.edu if (bits(FpSrcReg2_uqw, hiIndex)) 3176594Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, arg1Bits); 3186594Sgblack@eecs.umich.edu } 3198588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 3206594Sgblack@eecs.umich.edu ''' 3216594Sgblack@eecs.umich.edu 3226596Sgblack@eecs.umich.edu class shuffle(MediaOp): 32312707Sgabeblack@google.com op_class = 'SimdMiscOp' 3246596Sgblack@eecs.umich.edu code = ''' 3256596Sgblack@eecs.umich.edu assert(srcSize == destSize); 3266596Sgblack@eecs.umich.edu int size = srcSize; 3276596Sgblack@eecs.umich.edu int sizeBits = size * 8; 3286596Sgblack@eecs.umich.edu int items = sizeof(FloatRegBits) / size; 3296596Sgblack@eecs.umich.edu int options; 3306596Sgblack@eecs.umich.edu int optionBits; 3316596Sgblack@eecs.umich.edu if (size == 8) { 3326596Sgblack@eecs.umich.edu options = 2; 3336596Sgblack@eecs.umich.edu optionBits = 1; 3346596Sgblack@eecs.umich.edu } else { 3356596Sgblack@eecs.umich.edu options = 4; 3366596Sgblack@eecs.umich.edu optionBits = 2; 3376596Sgblack@eecs.umich.edu } 3386596Sgblack@eecs.umich.edu 3396596Sgblack@eecs.umich.edu uint64_t result = 0; 3406596Sgblack@eecs.umich.edu uint8_t sel = ext; 3416596Sgblack@eecs.umich.edu 3426596Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 3436596Sgblack@eecs.umich.edu uint64_t resBits; 3446596Sgblack@eecs.umich.edu uint8_t lsel = sel & mask(optionBits); 3456596Sgblack@eecs.umich.edu if (lsel * size >= sizeof(FloatRegBits)) { 3466596Sgblack@eecs.umich.edu lsel -= options / 2; 3478588Sgblack@eecs.umich.edu resBits = bits(FpSrcReg2_uqw, 3486596Sgblack@eecs.umich.edu (lsel + 1) * sizeBits - 1, 3496596Sgblack@eecs.umich.edu (lsel + 0) * sizeBits); 3506596Sgblack@eecs.umich.edu } else { 3518588Sgblack@eecs.umich.edu resBits = bits(FpSrcReg1_uqw, 3526596Sgblack@eecs.umich.edu (lsel + 1) * sizeBits - 1, 3536596Sgblack@eecs.umich.edu (lsel + 0) * sizeBits); 3546596Sgblack@eecs.umich.edu } 3556596Sgblack@eecs.umich.edu 3566596Sgblack@eecs.umich.edu sel >>= optionBits; 3576596Sgblack@eecs.umich.edu 3586596Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 3596596Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 3606596Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 3616596Sgblack@eecs.umich.edu } 3628588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 3636596Sgblack@eecs.umich.edu ''' 3646596Sgblack@eecs.umich.edu 3656521Sgblack@eecs.umich.edu class Unpack(MediaOp): 36612707Sgabeblack@google.com op_class = 'SimdMiscOp' 3676521Sgblack@eecs.umich.edu code = ''' 3686521Sgblack@eecs.umich.edu assert(srcSize == destSize); 3696521Sgblack@eecs.umich.edu int size = destSize; 3706521Sgblack@eecs.umich.edu int items = (sizeof(FloatRegBits) / size) / 2; 3716545Sgblack@eecs.umich.edu int offset = ext ? items : 0; 3726521Sgblack@eecs.umich.edu uint64_t result = 0; 3736521Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 3746521Sgblack@eecs.umich.edu uint64_t pickedLow = 3758588Sgblack@eecs.umich.edu bits(FpSrcReg1_uqw, (i + offset + 1) * 8 * size - 1, 3766521Sgblack@eecs.umich.edu (i + offset) * 8 * size); 3776521Sgblack@eecs.umich.edu result = insertBits(result, 3786521Sgblack@eecs.umich.edu (2 * i + 1) * 8 * size - 1, 3796521Sgblack@eecs.umich.edu (2 * i + 0) * 8 * size, 3806521Sgblack@eecs.umich.edu pickedLow); 3816521Sgblack@eecs.umich.edu uint64_t pickedHigh = 3828588Sgblack@eecs.umich.edu bits(FpSrcReg2_uqw, (i + offset + 1) * 8 * size - 1, 3836521Sgblack@eecs.umich.edu (i + offset) * 8 * size); 3846521Sgblack@eecs.umich.edu result = insertBits(result, 3856521Sgblack@eecs.umich.edu (2 * i + 2) * 8 * size - 1, 3866521Sgblack@eecs.umich.edu (2 * i + 1) * 8 * size, 3876521Sgblack@eecs.umich.edu pickedHigh); 3886521Sgblack@eecs.umich.edu } 3898588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 3906521Sgblack@eecs.umich.edu ''' 3916534Sgblack@eecs.umich.edu 3926546Sgblack@eecs.umich.edu class Pack(MediaOp): 39312707Sgabeblack@google.com op_class = 'SimdMiscOp' 3946546Sgblack@eecs.umich.edu code = ''' 3956546Sgblack@eecs.umich.edu assert(srcSize == destSize * 2); 3966546Sgblack@eecs.umich.edu int items = (sizeof(FloatRegBits) / destSize); 3976546Sgblack@eecs.umich.edu int destBits = destSize * 8; 3986546Sgblack@eecs.umich.edu int srcBits = srcSize * 8; 3996546Sgblack@eecs.umich.edu uint64_t result = 0; 4006546Sgblack@eecs.umich.edu int i; 4016546Sgblack@eecs.umich.edu for (i = 0; i < items / 2; i++) { 4026546Sgblack@eecs.umich.edu uint64_t picked = 4038588Sgblack@eecs.umich.edu bits(FpSrcReg1_uqw, (i + 1) * srcBits - 1, 4046546Sgblack@eecs.umich.edu (i + 0) * srcBits); 4056546Sgblack@eecs.umich.edu unsigned signBit = bits(picked, srcBits - 1); 4066546Sgblack@eecs.umich.edu uint64_t overflow = bits(picked, srcBits - 1, destBits - 1); 4076546Sgblack@eecs.umich.edu 4086546Sgblack@eecs.umich.edu // Handle saturation. 4096546Sgblack@eecs.umich.edu if (signBit) { 4106546Sgblack@eecs.umich.edu if (overflow != mask(destBits - srcBits + 1)) { 4116801Sgblack@eecs.umich.edu if (signedOp()) 4126742Svince@csl.cornell.edu picked = (ULL(1) << (destBits - 1)); 4136546Sgblack@eecs.umich.edu else 4146546Sgblack@eecs.umich.edu picked = 0; 4156546Sgblack@eecs.umich.edu } 4166546Sgblack@eecs.umich.edu } else { 4176546Sgblack@eecs.umich.edu if (overflow != 0) { 4186801Sgblack@eecs.umich.edu if (signedOp()) 4196546Sgblack@eecs.umich.edu picked = mask(destBits - 1); 4206546Sgblack@eecs.umich.edu else 4216546Sgblack@eecs.umich.edu picked = mask(destBits); 4226546Sgblack@eecs.umich.edu } 4236546Sgblack@eecs.umich.edu } 4246546Sgblack@eecs.umich.edu result = insertBits(result, 4256546Sgblack@eecs.umich.edu (i + 1) * destBits - 1, 4266546Sgblack@eecs.umich.edu (i + 0) * destBits, 4276546Sgblack@eecs.umich.edu picked); 4286546Sgblack@eecs.umich.edu } 4296546Sgblack@eecs.umich.edu for (;i < items; i++) { 4306546Sgblack@eecs.umich.edu uint64_t picked = 4318588Sgblack@eecs.umich.edu bits(FpSrcReg2_uqw, (i - items + 1) * srcBits - 1, 4326546Sgblack@eecs.umich.edu (i - items + 0) * srcBits); 4336546Sgblack@eecs.umich.edu unsigned signBit = bits(picked, srcBits - 1); 4346546Sgblack@eecs.umich.edu uint64_t overflow = bits(picked, srcBits - 1, destBits - 1); 4356546Sgblack@eecs.umich.edu 4366546Sgblack@eecs.umich.edu // Handle saturation. 4376546Sgblack@eecs.umich.edu if (signBit) { 4386546Sgblack@eecs.umich.edu if (overflow != mask(destBits - srcBits + 1)) { 4396801Sgblack@eecs.umich.edu if (signedOp()) 4406742Svince@csl.cornell.edu picked = (ULL(1) << (destBits - 1)); 4416546Sgblack@eecs.umich.edu else 4426546Sgblack@eecs.umich.edu picked = 0; 4436546Sgblack@eecs.umich.edu } 4446546Sgblack@eecs.umich.edu } else { 4456546Sgblack@eecs.umich.edu if (overflow != 0) { 4466801Sgblack@eecs.umich.edu if (signedOp()) 4476546Sgblack@eecs.umich.edu picked = mask(destBits - 1); 4486546Sgblack@eecs.umich.edu else 4496546Sgblack@eecs.umich.edu picked = mask(destBits); 4506546Sgblack@eecs.umich.edu } 4516546Sgblack@eecs.umich.edu } 4526546Sgblack@eecs.umich.edu result = insertBits(result, 4536546Sgblack@eecs.umich.edu (i + 1) * destBits - 1, 4546546Sgblack@eecs.umich.edu (i + 0) * destBits, 4556546Sgblack@eecs.umich.edu picked); 4566546Sgblack@eecs.umich.edu } 4578588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 4586546Sgblack@eecs.umich.edu ''' 4596546Sgblack@eecs.umich.edu 4606534Sgblack@eecs.umich.edu class Mxor(MediaOp): 4616534Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2): 4626534Sgblack@eecs.umich.edu super(Mxor, self).__init__(dest, src1, src2, 1) 46312707Sgabeblack@google.com op_class = 'SimdAluOp' 4646534Sgblack@eecs.umich.edu code = ''' 4658588Sgblack@eecs.umich.edu FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw; 4666534Sgblack@eecs.umich.edu ''' 4676537Sgblack@eecs.umich.edu 4686537Sgblack@eecs.umich.edu class Mor(MediaOp): 4696537Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2): 4706537Sgblack@eecs.umich.edu super(Mor, self).__init__(dest, src1, src2, 1) 47112707Sgabeblack@google.com op_class = 'SimdAluOp' 4726537Sgblack@eecs.umich.edu code = ''' 4738588Sgblack@eecs.umich.edu FpDestReg_uqw = FpSrcReg1_uqw | FpSrcReg2_uqw; 4746537Sgblack@eecs.umich.edu ''' 4756539Sgblack@eecs.umich.edu 4766539Sgblack@eecs.umich.edu class Mand(MediaOp): 4776539Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2): 4786539Sgblack@eecs.umich.edu super(Mand, self).__init__(dest, src1, src2, 1) 47912707Sgabeblack@google.com op_class = 'SimdAluOp' 4806539Sgblack@eecs.umich.edu code = ''' 4818588Sgblack@eecs.umich.edu FpDestReg_uqw = FpSrcReg1_uqw & FpSrcReg2_uqw; 4826539Sgblack@eecs.umich.edu ''' 4836541Sgblack@eecs.umich.edu 4846541Sgblack@eecs.umich.edu class Mandn(MediaOp): 4856541Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2): 4866541Sgblack@eecs.umich.edu super(Mandn, self).__init__(dest, src1, src2, 1) 48712707Sgabeblack@google.com op_class = 'SimdAluOp' 4886541Sgblack@eecs.umich.edu code = ''' 4898588Sgblack@eecs.umich.edu FpDestReg_uqw = ~FpSrcReg1_uqw & FpSrcReg2_uqw; 4906541Sgblack@eecs.umich.edu ''' 4916548Sgblack@eecs.umich.edu 4926548Sgblack@eecs.umich.edu class Mminf(MediaOp): 49312707Sgabeblack@google.com op_class = 'SimdFloatCmpOp' 4946548Sgblack@eecs.umich.edu code = ''' 4956548Sgblack@eecs.umich.edu union floatInt 4966548Sgblack@eecs.umich.edu { 4976548Sgblack@eecs.umich.edu float f; 4986548Sgblack@eecs.umich.edu uint32_t i; 4996548Sgblack@eecs.umich.edu }; 5006548Sgblack@eecs.umich.edu union doubleInt 5016548Sgblack@eecs.umich.edu { 5026548Sgblack@eecs.umich.edu double d; 5036548Sgblack@eecs.umich.edu uint64_t i; 5046548Sgblack@eecs.umich.edu }; 5056548Sgblack@eecs.umich.edu 5066548Sgblack@eecs.umich.edu assert(srcSize == destSize); 5076548Sgblack@eecs.umich.edu int size = srcSize; 5086548Sgblack@eecs.umich.edu int sizeBits = size * 8; 5096548Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 5106799Sgblack@eecs.umich.edu int items = numItems(size); 5118588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 5126548Sgblack@eecs.umich.edu 5136548Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 5146548Sgblack@eecs.umich.edu double arg1, arg2; 5156548Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 5166548Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 5178588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 5188588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 5196548Sgblack@eecs.umich.edu 5206548Sgblack@eecs.umich.edu if (size == 4) { 5216548Sgblack@eecs.umich.edu floatInt fi; 5226548Sgblack@eecs.umich.edu fi.i = arg1Bits; 5236548Sgblack@eecs.umich.edu arg1 = fi.f; 5246548Sgblack@eecs.umich.edu fi.i = arg2Bits; 5256548Sgblack@eecs.umich.edu arg2 = fi.f; 5266548Sgblack@eecs.umich.edu } else { 5276548Sgblack@eecs.umich.edu doubleInt di; 5286548Sgblack@eecs.umich.edu di.i = arg1Bits; 5296548Sgblack@eecs.umich.edu arg1 = di.d; 5306548Sgblack@eecs.umich.edu di.i = arg2Bits; 5316548Sgblack@eecs.umich.edu arg2 = di.d; 5326548Sgblack@eecs.umich.edu } 5336548Sgblack@eecs.umich.edu 5346548Sgblack@eecs.umich.edu if (arg1 < arg2) { 5356548Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, arg1Bits); 5366548Sgblack@eecs.umich.edu } else { 5376548Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, arg2Bits); 5386548Sgblack@eecs.umich.edu } 5396548Sgblack@eecs.umich.edu } 5408588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 5416548Sgblack@eecs.umich.edu ''' 5426550Sgblack@eecs.umich.edu 5436550Sgblack@eecs.umich.edu class Mmaxf(MediaOp): 54412707Sgabeblack@google.com op_class = 'SimdFloatCmpOp' 5456550Sgblack@eecs.umich.edu code = ''' 5466550Sgblack@eecs.umich.edu union floatInt 5476550Sgblack@eecs.umich.edu { 5486550Sgblack@eecs.umich.edu float f; 5496550Sgblack@eecs.umich.edu uint32_t i; 5506550Sgblack@eecs.umich.edu }; 5516550Sgblack@eecs.umich.edu union doubleInt 5526550Sgblack@eecs.umich.edu { 5536550Sgblack@eecs.umich.edu double d; 5546550Sgblack@eecs.umich.edu uint64_t i; 5556550Sgblack@eecs.umich.edu }; 5566550Sgblack@eecs.umich.edu 5576550Sgblack@eecs.umich.edu assert(srcSize == destSize); 5586550Sgblack@eecs.umich.edu int size = srcSize; 5596550Sgblack@eecs.umich.edu int sizeBits = size * 8; 5606550Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 5616799Sgblack@eecs.umich.edu int items = numItems(size); 5628588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 5636550Sgblack@eecs.umich.edu 5646550Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 5656550Sgblack@eecs.umich.edu double arg1, arg2; 5666550Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 5676550Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 5688588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 5698588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 5706550Sgblack@eecs.umich.edu 5716550Sgblack@eecs.umich.edu if (size == 4) { 5726550Sgblack@eecs.umich.edu floatInt fi; 5736550Sgblack@eecs.umich.edu fi.i = arg1Bits; 5746550Sgblack@eecs.umich.edu arg1 = fi.f; 5756550Sgblack@eecs.umich.edu fi.i = arg2Bits; 5766550Sgblack@eecs.umich.edu arg2 = fi.f; 5776550Sgblack@eecs.umich.edu } else { 5786550Sgblack@eecs.umich.edu doubleInt di; 5796550Sgblack@eecs.umich.edu di.i = arg1Bits; 5806550Sgblack@eecs.umich.edu arg1 = di.d; 5816550Sgblack@eecs.umich.edu di.i = arg2Bits; 5826550Sgblack@eecs.umich.edu arg2 = di.d; 5836550Sgblack@eecs.umich.edu } 5846550Sgblack@eecs.umich.edu 5856550Sgblack@eecs.umich.edu if (arg1 > arg2) { 5866550Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, arg1Bits); 5876550Sgblack@eecs.umich.edu } else { 5886550Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, arg2Bits); 5896550Sgblack@eecs.umich.edu } 5906550Sgblack@eecs.umich.edu } 5918588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 5926550Sgblack@eecs.umich.edu ''' 5936552Sgblack@eecs.umich.edu 5946572Sgblack@eecs.umich.edu class Mmini(MediaOp): 59512707Sgabeblack@google.com op_class = 'SimdCmpOp' 5966572Sgblack@eecs.umich.edu code = ''' 5976572Sgblack@eecs.umich.edu 5986572Sgblack@eecs.umich.edu assert(srcSize == destSize); 5996572Sgblack@eecs.umich.edu int size = srcSize; 6006572Sgblack@eecs.umich.edu int sizeBits = size * 8; 6016799Sgblack@eecs.umich.edu int items = numItems(size); 6028588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 6036572Sgblack@eecs.umich.edu 6046572Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 6056572Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 6066572Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 6078588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 6086572Sgblack@eecs.umich.edu int64_t arg1 = arg1Bits | 6096742Svince@csl.cornell.edu (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); 6108588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 6116572Sgblack@eecs.umich.edu int64_t arg2 = arg2Bits | 6126742Svince@csl.cornell.edu (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); 6136572Sgblack@eecs.umich.edu uint64_t resBits; 6146572Sgblack@eecs.umich.edu 6156801Sgblack@eecs.umich.edu if (signedOp()) { 6166572Sgblack@eecs.umich.edu if (arg1 < arg2) { 6176572Sgblack@eecs.umich.edu resBits = arg1Bits; 6186572Sgblack@eecs.umich.edu } else { 6196572Sgblack@eecs.umich.edu resBits = arg2Bits; 6206572Sgblack@eecs.umich.edu } 6216572Sgblack@eecs.umich.edu } else { 6226572Sgblack@eecs.umich.edu if (arg1Bits < arg2Bits) { 6236572Sgblack@eecs.umich.edu resBits = arg1Bits; 6246572Sgblack@eecs.umich.edu } else { 6256572Sgblack@eecs.umich.edu resBits = arg2Bits; 6266572Sgblack@eecs.umich.edu } 6276572Sgblack@eecs.umich.edu } 6286572Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 6296572Sgblack@eecs.umich.edu } 6308588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 6316572Sgblack@eecs.umich.edu ''' 6326572Sgblack@eecs.umich.edu 6336574Sgblack@eecs.umich.edu class Mmaxi(MediaOp): 63412707Sgabeblack@google.com op_class = 'SimdCmpOp' 6356574Sgblack@eecs.umich.edu code = ''' 6366574Sgblack@eecs.umich.edu 6376574Sgblack@eecs.umich.edu assert(srcSize == destSize); 6386574Sgblack@eecs.umich.edu int size = srcSize; 6396574Sgblack@eecs.umich.edu int sizeBits = size * 8; 6406799Sgblack@eecs.umich.edu int items = numItems(size); 6418588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 6426574Sgblack@eecs.umich.edu 6436574Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 6446574Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 6456574Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 6468588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 6476574Sgblack@eecs.umich.edu int64_t arg1 = arg1Bits | 6486742Svince@csl.cornell.edu (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); 6498588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 6506574Sgblack@eecs.umich.edu int64_t arg2 = arg2Bits | 6516742Svince@csl.cornell.edu (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); 6526574Sgblack@eecs.umich.edu uint64_t resBits; 6536574Sgblack@eecs.umich.edu 6546801Sgblack@eecs.umich.edu if (signedOp()) { 6556574Sgblack@eecs.umich.edu if (arg1 > arg2) { 6566574Sgblack@eecs.umich.edu resBits = arg1Bits; 6576574Sgblack@eecs.umich.edu } else { 6586574Sgblack@eecs.umich.edu resBits = arg2Bits; 6596574Sgblack@eecs.umich.edu } 6606574Sgblack@eecs.umich.edu } else { 6616574Sgblack@eecs.umich.edu if (arg1Bits > arg2Bits) { 6626574Sgblack@eecs.umich.edu resBits = arg1Bits; 6636574Sgblack@eecs.umich.edu } else { 6646574Sgblack@eecs.umich.edu resBits = arg2Bits; 6656574Sgblack@eecs.umich.edu } 6666574Sgblack@eecs.umich.edu } 6676574Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 6686574Sgblack@eecs.umich.edu } 6698588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 6706574Sgblack@eecs.umich.edu ''' 6716574Sgblack@eecs.umich.edu 6726552Sgblack@eecs.umich.edu class Msqrt(MediaOp): 67312707Sgabeblack@google.com op_class = 'SimdFloatSqrtOp' 6746552Sgblack@eecs.umich.edu def __init__(self, dest, src, \ 6756552Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 6766552Sgblack@eecs.umich.edu super(Msqrt, self).__init__(dest, src,\ 6776552Sgblack@eecs.umich.edu "InstRegIndex(0)", size, destSize, srcSize, ext) 6786552Sgblack@eecs.umich.edu code = ''' 6796552Sgblack@eecs.umich.edu union floatInt 6806552Sgblack@eecs.umich.edu { 6816552Sgblack@eecs.umich.edu float f; 6826552Sgblack@eecs.umich.edu uint32_t i; 6836552Sgblack@eecs.umich.edu }; 6846552Sgblack@eecs.umich.edu union doubleInt 6856552Sgblack@eecs.umich.edu { 6866552Sgblack@eecs.umich.edu double d; 6876552Sgblack@eecs.umich.edu uint64_t i; 6886552Sgblack@eecs.umich.edu }; 6896552Sgblack@eecs.umich.edu 6906552Sgblack@eecs.umich.edu assert(srcSize == destSize); 6916552Sgblack@eecs.umich.edu int size = srcSize; 6926552Sgblack@eecs.umich.edu int sizeBits = size * 8; 6936552Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 6946799Sgblack@eecs.umich.edu int items = numItems(size); 6958588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 6966552Sgblack@eecs.umich.edu 6976552Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 6986552Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 6996552Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 7008588Sgblack@eecs.umich.edu uint64_t argBits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 7016552Sgblack@eecs.umich.edu 7026552Sgblack@eecs.umich.edu if (size == 4) { 7036552Sgblack@eecs.umich.edu floatInt fi; 7046552Sgblack@eecs.umich.edu fi.i = argBits; 7056552Sgblack@eecs.umich.edu fi.f = sqrt(fi.f); 7066552Sgblack@eecs.umich.edu argBits = fi.i; 7076552Sgblack@eecs.umich.edu } else { 7086552Sgblack@eecs.umich.edu doubleInt di; 7096552Sgblack@eecs.umich.edu di.i = argBits; 7106552Sgblack@eecs.umich.edu di.d = sqrt(di.d); 7116552Sgblack@eecs.umich.edu argBits = di.i; 7126552Sgblack@eecs.umich.edu } 7136552Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, argBits); 7146552Sgblack@eecs.umich.edu } 7158588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 7166552Sgblack@eecs.umich.edu ''' 7176554Sgblack@eecs.umich.edu 71811160Ssteve.reinhardt@amd.com # compute approximate reciprocal --- single-precision only 71911160Ssteve.reinhardt@amd.com class Mrcp(MediaOp): 72011160Ssteve.reinhardt@amd.com def __init__(self, dest, src, \ 72111160Ssteve.reinhardt@amd.com size = None, destSize = None, srcSize = None, ext = None): 72211160Ssteve.reinhardt@amd.com super(Mrcp, self).__init__(dest, src,\ 72311160Ssteve.reinhardt@amd.com "InstRegIndex(0)", size, destSize, srcSize, ext) 72412707Sgabeblack@google.com op_class = 'SimdFloatAluOp' 72511160Ssteve.reinhardt@amd.com code = ''' 72611160Ssteve.reinhardt@amd.com union floatInt 72711160Ssteve.reinhardt@amd.com { 72811160Ssteve.reinhardt@amd.com float f; 72911160Ssteve.reinhardt@amd.com uint32_t i; 73011160Ssteve.reinhardt@amd.com }; 73111160Ssteve.reinhardt@amd.com 73211160Ssteve.reinhardt@amd.com assert(srcSize == 4); // ISA defines single-precision only 73311160Ssteve.reinhardt@amd.com assert(srcSize == destSize); 73411160Ssteve.reinhardt@amd.com const int size = 4; 73511160Ssteve.reinhardt@amd.com const int sizeBits = size * 8; 73611160Ssteve.reinhardt@amd.com int items = numItems(size); 73711160Ssteve.reinhardt@amd.com uint64_t result = FpDestReg_uqw; 73811160Ssteve.reinhardt@amd.com 73911160Ssteve.reinhardt@amd.com for (int i = 0; i < items; i++) { 74011160Ssteve.reinhardt@amd.com int hiIndex = (i + 1) * sizeBits - 1; 74111160Ssteve.reinhardt@amd.com int loIndex = (i + 0) * sizeBits; 74211160Ssteve.reinhardt@amd.com uint64_t argBits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 74311160Ssteve.reinhardt@amd.com 74411160Ssteve.reinhardt@amd.com floatInt fi; 74511160Ssteve.reinhardt@amd.com fi.i = argBits; 74611160Ssteve.reinhardt@amd.com // This is more accuracy than HW provides, but oh well 74711160Ssteve.reinhardt@amd.com fi.f = 1.0 / fi.f; 74811160Ssteve.reinhardt@amd.com argBits = fi.i; 74911160Ssteve.reinhardt@amd.com result = insertBits(result, hiIndex, loIndex, argBits); 75011160Ssteve.reinhardt@amd.com } 75111160Ssteve.reinhardt@amd.com FpDestReg_uqw = result; 75211160Ssteve.reinhardt@amd.com ''' 75311160Ssteve.reinhardt@amd.com 7546554Sgblack@eecs.umich.edu class Maddf(MediaOp): 75512707Sgabeblack@google.com op_class = 'SimdFloatAddOp' 7566554Sgblack@eecs.umich.edu code = ''' 7576554Sgblack@eecs.umich.edu union floatInt 7586554Sgblack@eecs.umich.edu { 7596554Sgblack@eecs.umich.edu float f; 7606554Sgblack@eecs.umich.edu uint32_t i; 7616554Sgblack@eecs.umich.edu }; 7626554Sgblack@eecs.umich.edu union doubleInt 7636554Sgblack@eecs.umich.edu { 7646554Sgblack@eecs.umich.edu double d; 7656554Sgblack@eecs.umich.edu uint64_t i; 7666554Sgblack@eecs.umich.edu }; 7676554Sgblack@eecs.umich.edu 7686554Sgblack@eecs.umich.edu assert(srcSize == destSize); 7696554Sgblack@eecs.umich.edu int size = srcSize; 7706554Sgblack@eecs.umich.edu int sizeBits = size * 8; 7716554Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 7726799Sgblack@eecs.umich.edu int items = numItems(size); 7738588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 7746554Sgblack@eecs.umich.edu 7756554Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 7766554Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 7776554Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 7788588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 7798588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 7806554Sgblack@eecs.umich.edu uint64_t resBits; 7816554Sgblack@eecs.umich.edu 7826554Sgblack@eecs.umich.edu if (size == 4) { 7836554Sgblack@eecs.umich.edu floatInt arg1, arg2, res; 7846554Sgblack@eecs.umich.edu arg1.i = arg1Bits; 7856554Sgblack@eecs.umich.edu arg2.i = arg2Bits; 7866554Sgblack@eecs.umich.edu res.f = arg1.f + arg2.f; 7876554Sgblack@eecs.umich.edu resBits = res.i; 7886554Sgblack@eecs.umich.edu } else { 7896554Sgblack@eecs.umich.edu doubleInt arg1, arg2, res; 7906554Sgblack@eecs.umich.edu arg1.i = arg1Bits; 7916554Sgblack@eecs.umich.edu arg2.i = arg2Bits; 7926554Sgblack@eecs.umich.edu res.d = arg1.d + arg2.d; 7936554Sgblack@eecs.umich.edu resBits = res.i; 7946554Sgblack@eecs.umich.edu } 7956554Sgblack@eecs.umich.edu 7966554Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 7976554Sgblack@eecs.umich.edu } 7988588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 7996554Sgblack@eecs.umich.edu ''' 8006556Sgblack@eecs.umich.edu 8016556Sgblack@eecs.umich.edu class Msubf(MediaOp): 80212707Sgabeblack@google.com op_class = 'SimdFloatAddOp' 8036556Sgblack@eecs.umich.edu code = ''' 8046556Sgblack@eecs.umich.edu union floatInt 8056556Sgblack@eecs.umich.edu { 8066556Sgblack@eecs.umich.edu float f; 8076556Sgblack@eecs.umich.edu uint32_t i; 8086556Sgblack@eecs.umich.edu }; 8096556Sgblack@eecs.umich.edu union doubleInt 8106556Sgblack@eecs.umich.edu { 8116556Sgblack@eecs.umich.edu double d; 8126556Sgblack@eecs.umich.edu uint64_t i; 8136556Sgblack@eecs.umich.edu }; 8146556Sgblack@eecs.umich.edu 8156556Sgblack@eecs.umich.edu assert(srcSize == destSize); 8166556Sgblack@eecs.umich.edu int size = srcSize; 8176556Sgblack@eecs.umich.edu int sizeBits = size * 8; 8186556Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 8196799Sgblack@eecs.umich.edu int items = numItems(size); 8208588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 8216556Sgblack@eecs.umich.edu 8226556Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 8236556Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 8246556Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 8258588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 8268588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 8276556Sgblack@eecs.umich.edu uint64_t resBits; 8286556Sgblack@eecs.umich.edu 8296556Sgblack@eecs.umich.edu if (size == 4) { 8306556Sgblack@eecs.umich.edu floatInt arg1, arg2, res; 8316556Sgblack@eecs.umich.edu arg1.i = arg1Bits; 8326556Sgblack@eecs.umich.edu arg2.i = arg2Bits; 8336556Sgblack@eecs.umich.edu res.f = arg1.f - arg2.f; 8346556Sgblack@eecs.umich.edu resBits = res.i; 8356556Sgblack@eecs.umich.edu } else { 8366556Sgblack@eecs.umich.edu doubleInt arg1, arg2, res; 8376556Sgblack@eecs.umich.edu arg1.i = arg1Bits; 8386556Sgblack@eecs.umich.edu arg2.i = arg2Bits; 8396556Sgblack@eecs.umich.edu res.d = arg1.d - arg2.d; 8406556Sgblack@eecs.umich.edu resBits = res.i; 8416556Sgblack@eecs.umich.edu } 8426556Sgblack@eecs.umich.edu 8436556Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 8446556Sgblack@eecs.umich.edu } 8458588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 8466556Sgblack@eecs.umich.edu ''' 8476558Sgblack@eecs.umich.edu 8486558Sgblack@eecs.umich.edu class Mmulf(MediaOp): 84912707Sgabeblack@google.com op_class = 'SimdFloatMultOp' 8506558Sgblack@eecs.umich.edu code = ''' 8516558Sgblack@eecs.umich.edu union floatInt 8526558Sgblack@eecs.umich.edu { 8536558Sgblack@eecs.umich.edu float f; 8546558Sgblack@eecs.umich.edu uint32_t i; 8556558Sgblack@eecs.umich.edu }; 8566558Sgblack@eecs.umich.edu union doubleInt 8576558Sgblack@eecs.umich.edu { 8586558Sgblack@eecs.umich.edu double d; 8596558Sgblack@eecs.umich.edu uint64_t i; 8606558Sgblack@eecs.umich.edu }; 8616558Sgblack@eecs.umich.edu 8626558Sgblack@eecs.umich.edu assert(srcSize == destSize); 8636558Sgblack@eecs.umich.edu int size = srcSize; 8646558Sgblack@eecs.umich.edu int sizeBits = size * 8; 8656558Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 8666799Sgblack@eecs.umich.edu int items = numItems(size); 8678588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 8686558Sgblack@eecs.umich.edu 8696558Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 8706558Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 8716558Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 8728588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 8738588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 8746558Sgblack@eecs.umich.edu uint64_t resBits; 8756558Sgblack@eecs.umich.edu 8766558Sgblack@eecs.umich.edu if (size == 4) { 8776558Sgblack@eecs.umich.edu floatInt arg1, arg2, res; 8786558Sgblack@eecs.umich.edu arg1.i = arg1Bits; 8796558Sgblack@eecs.umich.edu arg2.i = arg2Bits; 8806558Sgblack@eecs.umich.edu res.f = arg1.f * arg2.f; 8816558Sgblack@eecs.umich.edu resBits = res.i; 8826558Sgblack@eecs.umich.edu } else { 8836558Sgblack@eecs.umich.edu doubleInt arg1, arg2, res; 8846558Sgblack@eecs.umich.edu arg1.i = arg1Bits; 8856558Sgblack@eecs.umich.edu arg2.i = arg2Bits; 8866558Sgblack@eecs.umich.edu res.d = arg1.d * arg2.d; 8876558Sgblack@eecs.umich.edu resBits = res.i; 8886558Sgblack@eecs.umich.edu } 8896558Sgblack@eecs.umich.edu 8906558Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 8916558Sgblack@eecs.umich.edu } 8928588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 8936558Sgblack@eecs.umich.edu ''' 8946560Sgblack@eecs.umich.edu 8956560Sgblack@eecs.umich.edu class Mdivf(MediaOp): 89612707Sgabeblack@google.com op_class = 'SimdFloatDivOp' 8976560Sgblack@eecs.umich.edu code = ''' 8986560Sgblack@eecs.umich.edu union floatInt 8996560Sgblack@eecs.umich.edu { 9006560Sgblack@eecs.umich.edu float f; 9016560Sgblack@eecs.umich.edu uint32_t i; 9026560Sgblack@eecs.umich.edu }; 9036560Sgblack@eecs.umich.edu union doubleInt 9046560Sgblack@eecs.umich.edu { 9056560Sgblack@eecs.umich.edu double d; 9066560Sgblack@eecs.umich.edu uint64_t i; 9076560Sgblack@eecs.umich.edu }; 9086560Sgblack@eecs.umich.edu 9096560Sgblack@eecs.umich.edu assert(srcSize == destSize); 9106560Sgblack@eecs.umich.edu int size = srcSize; 9116560Sgblack@eecs.umich.edu int sizeBits = size * 8; 9126560Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 9136799Sgblack@eecs.umich.edu int items = numItems(size); 9148588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 9156560Sgblack@eecs.umich.edu 9166560Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 9176560Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 9186560Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 9198588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 9208588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 9216560Sgblack@eecs.umich.edu uint64_t resBits; 9226560Sgblack@eecs.umich.edu 9236560Sgblack@eecs.umich.edu if (size == 4) { 9246560Sgblack@eecs.umich.edu floatInt arg1, arg2, res; 9256560Sgblack@eecs.umich.edu arg1.i = arg1Bits; 9266560Sgblack@eecs.umich.edu arg2.i = arg2Bits; 9276560Sgblack@eecs.umich.edu res.f = arg1.f / arg2.f; 9286560Sgblack@eecs.umich.edu resBits = res.i; 9296560Sgblack@eecs.umich.edu } else { 9306560Sgblack@eecs.umich.edu doubleInt arg1, arg2, res; 9316560Sgblack@eecs.umich.edu arg1.i = arg1Bits; 9326560Sgblack@eecs.umich.edu arg2.i = arg2Bits; 9336560Sgblack@eecs.umich.edu res.d = arg1.d / arg2.d; 9346560Sgblack@eecs.umich.edu resBits = res.i; 9356560Sgblack@eecs.umich.edu } 9366560Sgblack@eecs.umich.edu 9376560Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 9386560Sgblack@eecs.umich.edu } 9398588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 9406560Sgblack@eecs.umich.edu ''' 9416562Sgblack@eecs.umich.edu 9426570Sgblack@eecs.umich.edu class Maddi(MediaOp): 94312707Sgabeblack@google.com op_class = 'SimdAddOp' 9446570Sgblack@eecs.umich.edu code = ''' 9456570Sgblack@eecs.umich.edu assert(srcSize == destSize); 9466570Sgblack@eecs.umich.edu int size = srcSize; 9476570Sgblack@eecs.umich.edu int sizeBits = size * 8; 9486799Sgblack@eecs.umich.edu int items = numItems(size); 9498588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 9506570Sgblack@eecs.umich.edu 9516570Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 9526570Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 9536570Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 9548588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 9558588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 9566570Sgblack@eecs.umich.edu uint64_t resBits = arg1Bits + arg2Bits; 95711320Ssteve.reinhardt@amd.com 9586570Sgblack@eecs.umich.edu if (ext & 0x2) { 9596801Sgblack@eecs.umich.edu if (signedOp()) { 9606801Sgblack@eecs.umich.edu int arg1Sign = bits(arg1Bits, sizeBits - 1); 9616801Sgblack@eecs.umich.edu int arg2Sign = bits(arg2Bits, sizeBits - 1); 9626801Sgblack@eecs.umich.edu int resSign = bits(resBits, sizeBits - 1); 9636801Sgblack@eecs.umich.edu if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { 9646801Sgblack@eecs.umich.edu if (resSign == 0) 9656801Sgblack@eecs.umich.edu resBits = (ULL(1) << (sizeBits - 1)); 9666801Sgblack@eecs.umich.edu else 9676801Sgblack@eecs.umich.edu resBits = mask(sizeBits - 1); 9686801Sgblack@eecs.umich.edu } 9696801Sgblack@eecs.umich.edu } else { 9706801Sgblack@eecs.umich.edu if (findCarry(sizeBits, resBits, arg1Bits, arg2Bits)) 9716801Sgblack@eecs.umich.edu resBits = mask(sizeBits); 9726570Sgblack@eecs.umich.edu } 9736570Sgblack@eecs.umich.edu } 9746570Sgblack@eecs.umich.edu 9756570Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 9766570Sgblack@eecs.umich.edu } 9778588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 9786570Sgblack@eecs.umich.edu ''' 9796570Sgblack@eecs.umich.edu 9806579Sgblack@eecs.umich.edu class Msubi(MediaOp): 98112707Sgabeblack@google.com op_class = 'SimdAddOp' 9826579Sgblack@eecs.umich.edu code = ''' 9836579Sgblack@eecs.umich.edu assert(srcSize == destSize); 9846579Sgblack@eecs.umich.edu int size = srcSize; 9856579Sgblack@eecs.umich.edu int sizeBits = size * 8; 9866799Sgblack@eecs.umich.edu int items = numItems(size); 9878588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 9886579Sgblack@eecs.umich.edu 9896579Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 9906579Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 9916579Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 9928588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 9938588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 9946579Sgblack@eecs.umich.edu uint64_t resBits = arg1Bits - arg2Bits; 99511320Ssteve.reinhardt@amd.com 9966579Sgblack@eecs.umich.edu if (ext & 0x2) { 9976801Sgblack@eecs.umich.edu if (signedOp()) { 9986801Sgblack@eecs.umich.edu int arg1Sign = bits(arg1Bits, sizeBits - 1); 9996801Sgblack@eecs.umich.edu int arg2Sign = !bits(arg2Bits, sizeBits - 1); 10006801Sgblack@eecs.umich.edu int resSign = bits(resBits, sizeBits - 1); 10016801Sgblack@eecs.umich.edu if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { 10026801Sgblack@eecs.umich.edu if (resSign == 0) 10036801Sgblack@eecs.umich.edu resBits = (ULL(1) << (sizeBits - 1)); 10046801Sgblack@eecs.umich.edu else 10056801Sgblack@eecs.umich.edu resBits = mask(sizeBits - 1); 10066801Sgblack@eecs.umich.edu } 10076801Sgblack@eecs.umich.edu } else { 10086801Sgblack@eecs.umich.edu if (arg2Bits > arg1Bits) { 10096801Sgblack@eecs.umich.edu resBits = 0; 10106801Sgblack@eecs.umich.edu } else if (!findCarry(sizeBits, resBits, 10116801Sgblack@eecs.umich.edu arg1Bits, ~arg2Bits)) { 10126801Sgblack@eecs.umich.edu resBits = mask(sizeBits); 10136801Sgblack@eecs.umich.edu } 10146579Sgblack@eecs.umich.edu } 10156579Sgblack@eecs.umich.edu } 10166579Sgblack@eecs.umich.edu 10176579Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 10186579Sgblack@eecs.umich.edu } 10198588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 10206579Sgblack@eecs.umich.edu ''' 10216579Sgblack@eecs.umich.edu 10226577Sgblack@eecs.umich.edu class Mmuli(MediaOp): 102312707Sgabeblack@google.com op_class = 'SimdMultOp' 10246577Sgblack@eecs.umich.edu code = ''' 10256577Sgblack@eecs.umich.edu int srcBits = srcSize * 8; 10266577Sgblack@eecs.umich.edu int destBits = destSize * 8; 10276577Sgblack@eecs.umich.edu assert(destBits <= 64); 10286577Sgblack@eecs.umich.edu assert(destSize >= srcSize); 10296799Sgblack@eecs.umich.edu int items = numItems(destSize); 10308588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 10316577Sgblack@eecs.umich.edu 10326577Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 10336585Sgblack@eecs.umich.edu int offset = 0; 10346585Sgblack@eecs.umich.edu if (ext & 16) { 10356585Sgblack@eecs.umich.edu if (ext & 32) 10366585Sgblack@eecs.umich.edu offset = i * (destBits - srcBits); 10376585Sgblack@eecs.umich.edu else 10386585Sgblack@eecs.umich.edu offset = i * (destBits - srcBits) + srcBits; 10396585Sgblack@eecs.umich.edu } 10406585Sgblack@eecs.umich.edu int srcHiIndex = (i + 1) * srcBits - 1 + offset; 10416585Sgblack@eecs.umich.edu int srcLoIndex = (i + 0) * srcBits + offset; 10428588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex); 10438588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, srcHiIndex, srcLoIndex); 10446577Sgblack@eecs.umich.edu uint64_t resBits; 10456577Sgblack@eecs.umich.edu 10466801Sgblack@eecs.umich.edu if (signedOp()) { 10476577Sgblack@eecs.umich.edu int64_t arg1 = arg1Bits | 10486742Svince@csl.cornell.edu (0 - (arg1Bits & (ULL(1) << (srcBits - 1)))); 10496577Sgblack@eecs.umich.edu int64_t arg2 = arg2Bits | 10506742Svince@csl.cornell.edu (0 - (arg2Bits & (ULL(1) << (srcBits - 1)))); 10516577Sgblack@eecs.umich.edu resBits = (uint64_t)(arg1 * arg2); 10526577Sgblack@eecs.umich.edu } else { 10536577Sgblack@eecs.umich.edu resBits = arg1Bits * arg2Bits; 10546577Sgblack@eecs.umich.edu } 10556577Sgblack@eecs.umich.edu 10566577Sgblack@eecs.umich.edu if (ext & 0x4) 10576742Svince@csl.cornell.edu resBits += (ULL(1) << (destBits - 1)); 105811320Ssteve.reinhardt@amd.com 10596800Sgblack@eecs.umich.edu if (multHi()) 10606577Sgblack@eecs.umich.edu resBits >>= destBits; 10616577Sgblack@eecs.umich.edu 10626577Sgblack@eecs.umich.edu int destHiIndex = (i + 1) * destBits - 1; 10636577Sgblack@eecs.umich.edu int destLoIndex = (i + 0) * destBits; 10646577Sgblack@eecs.umich.edu result = insertBits(result, destHiIndex, destLoIndex, resBits); 10656577Sgblack@eecs.umich.edu } 10668588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 10676577Sgblack@eecs.umich.edu ''' 10686577Sgblack@eecs.umich.edu 10696587Sgblack@eecs.umich.edu class Mavg(MediaOp): 107012707Sgabeblack@google.com op_class = 'SimdAddOp' 10716587Sgblack@eecs.umich.edu code = ''' 10726587Sgblack@eecs.umich.edu assert(srcSize == destSize); 10736587Sgblack@eecs.umich.edu int size = srcSize; 10746587Sgblack@eecs.umich.edu int sizeBits = size * 8; 10756799Sgblack@eecs.umich.edu int items = numItems(size); 10768588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 10776587Sgblack@eecs.umich.edu 10786587Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 10796587Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 10806587Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 10818588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 10828588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 10836587Sgblack@eecs.umich.edu uint64_t resBits = (arg1Bits + arg2Bits + 1) / 2; 108411320Ssteve.reinhardt@amd.com 10856587Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 10866587Sgblack@eecs.umich.edu } 10878588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 10886587Sgblack@eecs.umich.edu ''' 10896587Sgblack@eecs.umich.edu 10906581Sgblack@eecs.umich.edu class Msad(MediaOp): 109112707Sgabeblack@google.com op_class = 'SimdAddOp' 10926581Sgblack@eecs.umich.edu code = ''' 10936581Sgblack@eecs.umich.edu int srcBits = srcSize * 8; 10946581Sgblack@eecs.umich.edu int items = sizeof(FloatRegBits) / srcSize; 10956581Sgblack@eecs.umich.edu 10966581Sgblack@eecs.umich.edu uint64_t sum = 0; 10976581Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 10986581Sgblack@eecs.umich.edu int hiIndex = (i + 1) * srcBits - 1; 10996581Sgblack@eecs.umich.edu int loIndex = (i + 0) * srcBits; 11008588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 11018588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 11026581Sgblack@eecs.umich.edu int64_t resBits = arg1Bits - arg2Bits; 11036581Sgblack@eecs.umich.edu if (resBits < 0) 11046581Sgblack@eecs.umich.edu resBits = -resBits; 11056581Sgblack@eecs.umich.edu sum += resBits; 11066581Sgblack@eecs.umich.edu } 11078588Sgblack@eecs.umich.edu FpDestReg_uqw = sum & mask(destSize * 8); 11086581Sgblack@eecs.umich.edu ''' 11096581Sgblack@eecs.umich.edu 11106583Sgblack@eecs.umich.edu class Msrl(MediaOp): 111112707Sgabeblack@google.com op_class = 'SimdShiftOp' 11126583Sgblack@eecs.umich.edu code = ''' 11136583Sgblack@eecs.umich.edu 11146583Sgblack@eecs.umich.edu assert(srcSize == destSize); 11156583Sgblack@eecs.umich.edu int size = srcSize; 11166583Sgblack@eecs.umich.edu int sizeBits = size * 8; 11176799Sgblack@eecs.umich.edu int items = numItems(size); 11188588Sgblack@eecs.umich.edu uint64_t shiftAmt = op2_uqw; 11198588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 11206583Sgblack@eecs.umich.edu 11216583Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 11226583Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 11236583Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 11248588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 11256583Sgblack@eecs.umich.edu uint64_t resBits; 11266583Sgblack@eecs.umich.edu if (shiftAmt >= sizeBits) { 11276583Sgblack@eecs.umich.edu resBits = 0; 11286583Sgblack@eecs.umich.edu } else { 11296583Sgblack@eecs.umich.edu resBits = (arg1Bits >> shiftAmt) & 11306583Sgblack@eecs.umich.edu mask(sizeBits - shiftAmt); 11316583Sgblack@eecs.umich.edu } 11326583Sgblack@eecs.umich.edu 11336583Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 11346583Sgblack@eecs.umich.edu } 11358588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 11366583Sgblack@eecs.umich.edu ''' 11376583Sgblack@eecs.umich.edu 11386583Sgblack@eecs.umich.edu class Msra(MediaOp): 113912707Sgabeblack@google.com op_class = 'SimdShiftOp' 11406583Sgblack@eecs.umich.edu code = ''' 11416583Sgblack@eecs.umich.edu 11426583Sgblack@eecs.umich.edu assert(srcSize == destSize); 11436583Sgblack@eecs.umich.edu int size = srcSize; 11446583Sgblack@eecs.umich.edu int sizeBits = size * 8; 11456799Sgblack@eecs.umich.edu int items = numItems(size); 11468588Sgblack@eecs.umich.edu uint64_t shiftAmt = op2_uqw; 11478588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 11486583Sgblack@eecs.umich.edu 11496583Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 11506583Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 11516583Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 11528588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 11536583Sgblack@eecs.umich.edu uint64_t resBits; 11546583Sgblack@eecs.umich.edu if (shiftAmt >= sizeBits) { 11556583Sgblack@eecs.umich.edu if (bits(arg1Bits, sizeBits - 1)) 11566583Sgblack@eecs.umich.edu resBits = mask(sizeBits); 11576583Sgblack@eecs.umich.edu else 11586583Sgblack@eecs.umich.edu resBits = 0; 11596583Sgblack@eecs.umich.edu } else { 11606583Sgblack@eecs.umich.edu resBits = (arg1Bits >> shiftAmt); 11616583Sgblack@eecs.umich.edu resBits = resBits | 11626742Svince@csl.cornell.edu (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt)))); 11636583Sgblack@eecs.umich.edu } 11646583Sgblack@eecs.umich.edu 11656583Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 11666583Sgblack@eecs.umich.edu } 11678588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 11686583Sgblack@eecs.umich.edu ''' 11696583Sgblack@eecs.umich.edu 11706583Sgblack@eecs.umich.edu class Msll(MediaOp): 117112707Sgabeblack@google.com op_class = 'SimdShiftOp' 11726583Sgblack@eecs.umich.edu code = ''' 11736583Sgblack@eecs.umich.edu 11746583Sgblack@eecs.umich.edu assert(srcSize == destSize); 11756583Sgblack@eecs.umich.edu int size = srcSize; 11766583Sgblack@eecs.umich.edu int sizeBits = size * 8; 11776799Sgblack@eecs.umich.edu int items = numItems(size); 11788588Sgblack@eecs.umich.edu uint64_t shiftAmt = op2_uqw; 11798588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 11806583Sgblack@eecs.umich.edu 11816583Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 11826583Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 11836583Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 11848588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 11856583Sgblack@eecs.umich.edu uint64_t resBits; 11866583Sgblack@eecs.umich.edu if (shiftAmt >= sizeBits) { 11876583Sgblack@eecs.umich.edu resBits = 0; 11886583Sgblack@eecs.umich.edu } else { 11896583Sgblack@eecs.umich.edu resBits = (arg1Bits << shiftAmt); 11906583Sgblack@eecs.umich.edu } 11916583Sgblack@eecs.umich.edu 11926583Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 11936583Sgblack@eecs.umich.edu } 11948588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 11956583Sgblack@eecs.umich.edu ''' 11966583Sgblack@eecs.umich.edu 11976605Sgblack@eecs.umich.edu class Cvtf2i(MediaOp): 11986605Sgblack@eecs.umich.edu def __init__(self, dest, src, \ 11996605Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 12006605Sgblack@eecs.umich.edu super(Cvtf2i, self).__init__(dest, src,\ 12016605Sgblack@eecs.umich.edu "InstRegIndex(0)", size, destSize, srcSize, ext) 120212707Sgabeblack@google.com op_class = 'SimdFloatCvtOp' 12036605Sgblack@eecs.umich.edu code = ''' 12046605Sgblack@eecs.umich.edu union floatInt 12056605Sgblack@eecs.umich.edu { 12066605Sgblack@eecs.umich.edu float f; 12076605Sgblack@eecs.umich.edu uint32_t i; 12086605Sgblack@eecs.umich.edu }; 12096605Sgblack@eecs.umich.edu union doubleInt 12106605Sgblack@eecs.umich.edu { 12116605Sgblack@eecs.umich.edu double d; 12126605Sgblack@eecs.umich.edu uint64_t i; 12136605Sgblack@eecs.umich.edu }; 12146605Sgblack@eecs.umich.edu 12156605Sgblack@eecs.umich.edu assert(destSize == 4 || destSize == 8); 12166605Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 12176605Sgblack@eecs.umich.edu int srcSizeBits = srcSize * 8; 12186605Sgblack@eecs.umich.edu int destSizeBits = destSize * 8; 12196605Sgblack@eecs.umich.edu int items; 12206605Sgblack@eecs.umich.edu int srcStart = 0; 12216605Sgblack@eecs.umich.edu int destStart = 0; 12226605Sgblack@eecs.umich.edu if (srcSize == 2 * destSize) { 12236799Sgblack@eecs.umich.edu items = numItems(srcSize); 12246605Sgblack@eecs.umich.edu if (ext & 0x2) 12256605Sgblack@eecs.umich.edu destStart = destSizeBits * items; 12266605Sgblack@eecs.umich.edu } else if (destSize == 2 * srcSize) { 12276799Sgblack@eecs.umich.edu items = numItems(destSize); 12286605Sgblack@eecs.umich.edu if (ext & 0x2) 12296605Sgblack@eecs.umich.edu srcStart = srcSizeBits * items; 12306605Sgblack@eecs.umich.edu } else { 12316799Sgblack@eecs.umich.edu items = numItems(destSize); 12326605Sgblack@eecs.umich.edu } 12338588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 12346605Sgblack@eecs.umich.edu 12356605Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 12366605Sgblack@eecs.umich.edu int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; 12376605Sgblack@eecs.umich.edu int srcLoIndex = srcStart + (i + 0) * srcSizeBits; 12388588Sgblack@eecs.umich.edu uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex); 12396605Sgblack@eecs.umich.edu double arg; 12406605Sgblack@eecs.umich.edu 12416605Sgblack@eecs.umich.edu if (srcSize == 4) { 12426605Sgblack@eecs.umich.edu floatInt fi; 12436605Sgblack@eecs.umich.edu fi.i = argBits; 12446605Sgblack@eecs.umich.edu arg = fi.f; 12456605Sgblack@eecs.umich.edu } else { 12466605Sgblack@eecs.umich.edu doubleInt di; 12476605Sgblack@eecs.umich.edu di.i = argBits; 12486605Sgblack@eecs.umich.edu arg = di.d; 12496605Sgblack@eecs.umich.edu } 12506605Sgblack@eecs.umich.edu 12516605Sgblack@eecs.umich.edu if (ext & 0x4) { 12526605Sgblack@eecs.umich.edu if (arg >= 0) 12536605Sgblack@eecs.umich.edu arg += 0.5; 12546605Sgblack@eecs.umich.edu else 12556605Sgblack@eecs.umich.edu arg -= 0.5; 12566605Sgblack@eecs.umich.edu } 12576605Sgblack@eecs.umich.edu 12586605Sgblack@eecs.umich.edu if (destSize == 4) { 125911711Santhony.gutierrez@amd.com int32_t i_arg = (int32_t)arg; 126011711Santhony.gutierrez@amd.com argBits = *((uint32_t*)&i_arg); 12616605Sgblack@eecs.umich.edu } else { 126211711Santhony.gutierrez@amd.com int64_t i_arg = (int64_t)arg; 126311711Santhony.gutierrez@amd.com argBits = *((uint64_t*)&i_arg); 12646605Sgblack@eecs.umich.edu } 12656605Sgblack@eecs.umich.edu int destHiIndex = destStart + (i + 1) * destSizeBits - 1; 12666605Sgblack@eecs.umich.edu int destLoIndex = destStart + (i + 0) * destSizeBits; 12676605Sgblack@eecs.umich.edu result = insertBits(result, destHiIndex, destLoIndex, argBits); 12686605Sgblack@eecs.umich.edu } 12698588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 12706605Sgblack@eecs.umich.edu ''' 12716605Sgblack@eecs.umich.edu 12726562Sgblack@eecs.umich.edu class Cvti2f(MediaOp): 12736562Sgblack@eecs.umich.edu def __init__(self, dest, src, \ 12746562Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 12756562Sgblack@eecs.umich.edu super(Cvti2f, self).__init__(dest, src,\ 12766562Sgblack@eecs.umich.edu "InstRegIndex(0)", size, destSize, srcSize, ext) 127712707Sgabeblack@google.com op_class = 'SimdFloatCvtOp' 12786562Sgblack@eecs.umich.edu code = ''' 12796562Sgblack@eecs.umich.edu union floatInt 12806562Sgblack@eecs.umich.edu { 12816562Sgblack@eecs.umich.edu float f; 12826562Sgblack@eecs.umich.edu uint32_t i; 12836562Sgblack@eecs.umich.edu }; 12846562Sgblack@eecs.umich.edu union doubleInt 12856562Sgblack@eecs.umich.edu { 12866562Sgblack@eecs.umich.edu double d; 12876562Sgblack@eecs.umich.edu uint64_t i; 12886562Sgblack@eecs.umich.edu }; 12896562Sgblack@eecs.umich.edu 12906562Sgblack@eecs.umich.edu assert(destSize == 4 || destSize == 8); 12916562Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 12926562Sgblack@eecs.umich.edu int srcSizeBits = srcSize * 8; 12936562Sgblack@eecs.umich.edu int destSizeBits = destSize * 8; 12946562Sgblack@eecs.umich.edu int items; 12956562Sgblack@eecs.umich.edu int srcStart = 0; 12966562Sgblack@eecs.umich.edu int destStart = 0; 12976562Sgblack@eecs.umich.edu if (srcSize == 2 * destSize) { 12986799Sgblack@eecs.umich.edu items = numItems(srcSize); 12996562Sgblack@eecs.umich.edu if (ext & 0x2) 13006562Sgblack@eecs.umich.edu destStart = destSizeBits * items; 13016562Sgblack@eecs.umich.edu } else if (destSize == 2 * srcSize) { 13026799Sgblack@eecs.umich.edu items = numItems(destSize); 13036562Sgblack@eecs.umich.edu if (ext & 0x2) 13046562Sgblack@eecs.umich.edu srcStart = srcSizeBits * items; 13056562Sgblack@eecs.umich.edu } else { 13066799Sgblack@eecs.umich.edu items = numItems(destSize); 13076562Sgblack@eecs.umich.edu } 13088588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 13096562Sgblack@eecs.umich.edu 13106562Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 13116562Sgblack@eecs.umich.edu int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; 13126562Sgblack@eecs.umich.edu int srcLoIndex = srcStart + (i + 0) * srcSizeBits; 13138588Sgblack@eecs.umich.edu uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex); 13146742Svince@csl.cornell.edu 13157081Sgblack@eecs.umich.edu int64_t sArg = argBits | 13167081Sgblack@eecs.umich.edu (0 - (argBits & (ULL(1) << (srcSizeBits - 1)))); 13176562Sgblack@eecs.umich.edu double arg = sArg; 13186562Sgblack@eecs.umich.edu 13196562Sgblack@eecs.umich.edu if (destSize == 4) { 13206562Sgblack@eecs.umich.edu floatInt fi; 13216562Sgblack@eecs.umich.edu fi.f = arg; 13226562Sgblack@eecs.umich.edu argBits = fi.i; 13236562Sgblack@eecs.umich.edu } else { 13246562Sgblack@eecs.umich.edu doubleInt di; 13256562Sgblack@eecs.umich.edu di.d = arg; 13266562Sgblack@eecs.umich.edu argBits = di.i; 13276562Sgblack@eecs.umich.edu } 13286562Sgblack@eecs.umich.edu int destHiIndex = destStart + (i + 1) * destSizeBits - 1; 13296562Sgblack@eecs.umich.edu int destLoIndex = destStart + (i + 0) * destSizeBits; 13306562Sgblack@eecs.umich.edu result = insertBits(result, destHiIndex, destLoIndex, argBits); 13316562Sgblack@eecs.umich.edu } 13328588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 13336562Sgblack@eecs.umich.edu ''' 13346566Sgblack@eecs.umich.edu 13356568Sgblack@eecs.umich.edu class Cvtf2f(MediaOp): 13366568Sgblack@eecs.umich.edu def __init__(self, dest, src, \ 13376568Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 13386568Sgblack@eecs.umich.edu super(Cvtf2f, self).__init__(dest, src,\ 13396568Sgblack@eecs.umich.edu "InstRegIndex(0)", size, destSize, srcSize, ext) 134012707Sgabeblack@google.com op_class = 'SimdFloatCvtOp' 13416568Sgblack@eecs.umich.edu code = ''' 13426568Sgblack@eecs.umich.edu union floatInt 13436568Sgblack@eecs.umich.edu { 13446568Sgblack@eecs.umich.edu float f; 13456568Sgblack@eecs.umich.edu uint32_t i; 13466568Sgblack@eecs.umich.edu }; 13476568Sgblack@eecs.umich.edu union doubleInt 13486568Sgblack@eecs.umich.edu { 13496568Sgblack@eecs.umich.edu double d; 13506568Sgblack@eecs.umich.edu uint64_t i; 13516568Sgblack@eecs.umich.edu }; 13526568Sgblack@eecs.umich.edu 13536568Sgblack@eecs.umich.edu assert(destSize == 4 || destSize == 8); 13546568Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 13556568Sgblack@eecs.umich.edu int srcSizeBits = srcSize * 8; 13566568Sgblack@eecs.umich.edu int destSizeBits = destSize * 8; 13576568Sgblack@eecs.umich.edu int items; 13586568Sgblack@eecs.umich.edu int srcStart = 0; 13596568Sgblack@eecs.umich.edu int destStart = 0; 13606568Sgblack@eecs.umich.edu if (srcSize == 2 * destSize) { 13616799Sgblack@eecs.umich.edu items = numItems(srcSize); 13626568Sgblack@eecs.umich.edu if (ext & 0x2) 13636568Sgblack@eecs.umich.edu destStart = destSizeBits * items; 13646568Sgblack@eecs.umich.edu } else if (destSize == 2 * srcSize) { 13656799Sgblack@eecs.umich.edu items = numItems(destSize); 13666568Sgblack@eecs.umich.edu if (ext & 0x2) 13676568Sgblack@eecs.umich.edu srcStart = srcSizeBits * items; 13686568Sgblack@eecs.umich.edu } else { 13696799Sgblack@eecs.umich.edu items = numItems(destSize); 13706568Sgblack@eecs.umich.edu } 13718588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 13726568Sgblack@eecs.umich.edu 13736568Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 13746568Sgblack@eecs.umich.edu int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; 13756568Sgblack@eecs.umich.edu int srcLoIndex = srcStart + (i + 0) * srcSizeBits; 13768588Sgblack@eecs.umich.edu uint64_t argBits = bits(FpSrcReg1_uqw, srcHiIndex, srcLoIndex); 13776568Sgblack@eecs.umich.edu double arg; 13786568Sgblack@eecs.umich.edu 13796568Sgblack@eecs.umich.edu if (srcSize == 4) { 13806568Sgblack@eecs.umich.edu floatInt fi; 13816568Sgblack@eecs.umich.edu fi.i = argBits; 13826568Sgblack@eecs.umich.edu arg = fi.f; 13836568Sgblack@eecs.umich.edu } else { 13846568Sgblack@eecs.umich.edu doubleInt di; 13856568Sgblack@eecs.umich.edu di.i = argBits; 13866568Sgblack@eecs.umich.edu arg = di.d; 13876568Sgblack@eecs.umich.edu } 13886568Sgblack@eecs.umich.edu if (destSize == 4) { 13896568Sgblack@eecs.umich.edu floatInt fi; 13906568Sgblack@eecs.umich.edu fi.f = arg; 13916568Sgblack@eecs.umich.edu argBits = fi.i; 13926568Sgblack@eecs.umich.edu } else { 13936568Sgblack@eecs.umich.edu doubleInt di; 13946568Sgblack@eecs.umich.edu di.d = arg; 13956568Sgblack@eecs.umich.edu argBits = di.i; 13966568Sgblack@eecs.umich.edu } 13976568Sgblack@eecs.umich.edu int destHiIndex = destStart + (i + 1) * destSizeBits - 1; 13986568Sgblack@eecs.umich.edu int destLoIndex = destStart + (i + 0) * destSizeBits; 13996568Sgblack@eecs.umich.edu result = insertBits(result, destHiIndex, destLoIndex, argBits); 14006568Sgblack@eecs.umich.edu } 14018588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 14026568Sgblack@eecs.umich.edu ''' 14036568Sgblack@eecs.umich.edu 14046566Sgblack@eecs.umich.edu class Mcmpi2r(MediaOp): 140512707Sgabeblack@google.com op_class = 'SimdCvtOp' 14066566Sgblack@eecs.umich.edu code = ''' 14076566Sgblack@eecs.umich.edu union floatInt 14086566Sgblack@eecs.umich.edu { 14096566Sgblack@eecs.umich.edu float f; 14106566Sgblack@eecs.umich.edu uint32_t i; 14116566Sgblack@eecs.umich.edu }; 14126566Sgblack@eecs.umich.edu union doubleInt 14136566Sgblack@eecs.umich.edu { 14146566Sgblack@eecs.umich.edu double d; 14156566Sgblack@eecs.umich.edu uint64_t i; 14166566Sgblack@eecs.umich.edu }; 14176566Sgblack@eecs.umich.edu 14186566Sgblack@eecs.umich.edu assert(srcSize == destSize); 14196566Sgblack@eecs.umich.edu int size = srcSize; 14206566Sgblack@eecs.umich.edu int sizeBits = size * 8; 14216799Sgblack@eecs.umich.edu int items = numItems(size); 14228588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 14236566Sgblack@eecs.umich.edu 14246566Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 14256566Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 14266566Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 14278588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 14286566Sgblack@eecs.umich.edu int64_t arg1 = arg1Bits | 14296742Svince@csl.cornell.edu (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); 14308588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 14316566Sgblack@eecs.umich.edu int64_t arg2 = arg2Bits | 14326742Svince@csl.cornell.edu (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); 14336566Sgblack@eecs.umich.edu 14346566Sgblack@eecs.umich.edu uint64_t resBits = 0; 14356622Snate@binkert.org if (((ext & 0x2) == 0 && arg1 == arg2) || 14366622Snate@binkert.org ((ext & 0x2) == 0x2 && arg1 > arg2)) 14376566Sgblack@eecs.umich.edu resBits = mask(sizeBits); 14386566Sgblack@eecs.umich.edu 14396566Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 14406566Sgblack@eecs.umich.edu } 14418588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 14426566Sgblack@eecs.umich.edu ''' 14436601Sgblack@eecs.umich.edu 14446603Sgblack@eecs.umich.edu class Mcmpf2r(MediaOp): 144512707Sgabeblack@google.com op_class = 'SimdFloatCvtOp' 14466603Sgblack@eecs.umich.edu code = ''' 14476603Sgblack@eecs.umich.edu union floatInt 14486603Sgblack@eecs.umich.edu { 14496603Sgblack@eecs.umich.edu float f; 14506603Sgblack@eecs.umich.edu uint32_t i; 14516603Sgblack@eecs.umich.edu }; 14526603Sgblack@eecs.umich.edu union doubleInt 14536603Sgblack@eecs.umich.edu { 14546603Sgblack@eecs.umich.edu double d; 14556603Sgblack@eecs.umich.edu uint64_t i; 14566603Sgblack@eecs.umich.edu }; 14576603Sgblack@eecs.umich.edu 14586603Sgblack@eecs.umich.edu assert(srcSize == destSize); 14596603Sgblack@eecs.umich.edu int size = srcSize; 14606603Sgblack@eecs.umich.edu int sizeBits = size * 8; 14616799Sgblack@eecs.umich.edu int items = numItems(size); 14628588Sgblack@eecs.umich.edu uint64_t result = FpDestReg_uqw; 14636603Sgblack@eecs.umich.edu 14646603Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 14656603Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 14666603Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 14678588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, hiIndex, loIndex); 14688588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, hiIndex, loIndex); 14696603Sgblack@eecs.umich.edu double arg1, arg2; 14706603Sgblack@eecs.umich.edu 14716603Sgblack@eecs.umich.edu if (size == 4) { 14726603Sgblack@eecs.umich.edu floatInt fi; 14736603Sgblack@eecs.umich.edu fi.i = arg1Bits; 14746603Sgblack@eecs.umich.edu arg1 = fi.f; 14756603Sgblack@eecs.umich.edu fi.i = arg2Bits; 14766603Sgblack@eecs.umich.edu arg2 = fi.f; 14776603Sgblack@eecs.umich.edu } else { 14786603Sgblack@eecs.umich.edu doubleInt di; 14796603Sgblack@eecs.umich.edu di.i = arg1Bits; 14806603Sgblack@eecs.umich.edu arg1 = di.d; 14816603Sgblack@eecs.umich.edu di.i = arg2Bits; 14826603Sgblack@eecs.umich.edu arg2 = di.d; 14836603Sgblack@eecs.umich.edu } 14846603Sgblack@eecs.umich.edu 14856603Sgblack@eecs.umich.edu uint64_t resBits = 0; 14868946Sandreas.hansson@arm.com bool nanop = std::isnan(arg1) || std::isnan(arg2); 14876603Sgblack@eecs.umich.edu switch (ext & mask(3)) { 14886603Sgblack@eecs.umich.edu case 0: 14896603Sgblack@eecs.umich.edu if (arg1 == arg2 && !nanop) 14906603Sgblack@eecs.umich.edu resBits = mask(sizeBits); 14916603Sgblack@eecs.umich.edu break; 14926603Sgblack@eecs.umich.edu case 1: 14936603Sgblack@eecs.umich.edu if (arg1 < arg2 && !nanop) 14946603Sgblack@eecs.umich.edu resBits = mask(sizeBits); 14956603Sgblack@eecs.umich.edu break; 14966603Sgblack@eecs.umich.edu case 2: 14976603Sgblack@eecs.umich.edu if (arg1 <= arg2 && !nanop) 14986603Sgblack@eecs.umich.edu resBits = mask(sizeBits); 14996603Sgblack@eecs.umich.edu break; 15006603Sgblack@eecs.umich.edu case 3: 15016603Sgblack@eecs.umich.edu if (nanop) 15026603Sgblack@eecs.umich.edu resBits = mask(sizeBits); 15036603Sgblack@eecs.umich.edu break; 15046603Sgblack@eecs.umich.edu case 4: 15056603Sgblack@eecs.umich.edu if (arg1 != arg2 || nanop) 15066603Sgblack@eecs.umich.edu resBits = mask(sizeBits); 15076603Sgblack@eecs.umich.edu break; 15086603Sgblack@eecs.umich.edu case 5: 15096603Sgblack@eecs.umich.edu if (!(arg1 < arg2) || nanop) 15106603Sgblack@eecs.umich.edu resBits = mask(sizeBits); 15116603Sgblack@eecs.umich.edu break; 15126603Sgblack@eecs.umich.edu case 6: 15136603Sgblack@eecs.umich.edu if (!(arg1 <= arg2) || nanop) 15146603Sgblack@eecs.umich.edu resBits = mask(sizeBits); 15156603Sgblack@eecs.umich.edu break; 15166603Sgblack@eecs.umich.edu case 7: 15176603Sgblack@eecs.umich.edu if (!nanop) 15186603Sgblack@eecs.umich.edu resBits = mask(sizeBits); 15196603Sgblack@eecs.umich.edu break; 15206603Sgblack@eecs.umich.edu }; 15216603Sgblack@eecs.umich.edu 15226603Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 15236603Sgblack@eecs.umich.edu } 15248588Sgblack@eecs.umich.edu FpDestReg_uqw = result; 15256603Sgblack@eecs.umich.edu ''' 15266603Sgblack@eecs.umich.edu 15276601Sgblack@eecs.umich.edu class Mcmpf2rf(MediaOp): 15286601Sgblack@eecs.umich.edu def __init__(self, src1, src2,\ 15296601Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 15306601Sgblack@eecs.umich.edu super(Mcmpf2rf, self).__init__("InstRegIndex(0)", src1,\ 15316601Sgblack@eecs.umich.edu src2, size, destSize, srcSize, ext) 153212707Sgabeblack@google.com op_class = 'SimdFloatCvtOp' 15336601Sgblack@eecs.umich.edu code = ''' 15346601Sgblack@eecs.umich.edu union floatInt 15356601Sgblack@eecs.umich.edu { 15366601Sgblack@eecs.umich.edu float f; 15376601Sgblack@eecs.umich.edu uint32_t i; 15386601Sgblack@eecs.umich.edu }; 15396601Sgblack@eecs.umich.edu union doubleInt 15406601Sgblack@eecs.umich.edu { 15416601Sgblack@eecs.umich.edu double d; 15426601Sgblack@eecs.umich.edu uint64_t i; 15436601Sgblack@eecs.umich.edu }; 15446601Sgblack@eecs.umich.edu 15456601Sgblack@eecs.umich.edu assert(srcSize == destSize); 15466601Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 15476601Sgblack@eecs.umich.edu int size = srcSize; 15486601Sgblack@eecs.umich.edu int sizeBits = size * 8; 15496601Sgblack@eecs.umich.edu 15506601Sgblack@eecs.umich.edu double arg1, arg2; 15518588Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1_uqw, sizeBits - 1, 0); 15528588Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2_uqw, sizeBits - 1, 0); 15536601Sgblack@eecs.umich.edu if (size == 4) { 15546601Sgblack@eecs.umich.edu floatInt fi; 15556601Sgblack@eecs.umich.edu fi.i = arg1Bits; 15566601Sgblack@eecs.umich.edu arg1 = fi.f; 15576601Sgblack@eecs.umich.edu fi.i = arg2Bits; 15586601Sgblack@eecs.umich.edu arg2 = fi.f; 15596601Sgblack@eecs.umich.edu } else { 15606601Sgblack@eecs.umich.edu doubleInt di; 15616601Sgblack@eecs.umich.edu di.i = arg1Bits; 15626601Sgblack@eecs.umich.edu arg1 = di.d; 15636601Sgblack@eecs.umich.edu di.i = arg2Bits; 15646601Sgblack@eecs.umich.edu arg2 = di.d; 15656601Sgblack@eecs.umich.edu } 15666601Sgblack@eecs.umich.edu 15676601Sgblack@eecs.umich.edu // ZF PF CF 15686601Sgblack@eecs.umich.edu // Unordered 1 1 1 15696601Sgblack@eecs.umich.edu // Greater than 0 0 0 15706601Sgblack@eecs.umich.edu // Less than 0 0 1 15716601Sgblack@eecs.umich.edu // Equal 1 0 0 15726601Sgblack@eecs.umich.edu // OF = SF = AF = 0 15739010Snilay@cs.wisc.edu ccFlagBits = ccFlagBits & ~(SFBit | AFBit | ZFBit | PFBit); 15749010Snilay@cs.wisc.edu cfofBits = cfofBits & ~(OFBit | CFBit); 15759010Snilay@cs.wisc.edu 15769010Snilay@cs.wisc.edu if (std::isnan(arg1) || std::isnan(arg2)) { 15779010Snilay@cs.wisc.edu ccFlagBits = ccFlagBits | (ZFBit | PFBit); 15789010Snilay@cs.wisc.edu cfofBits = cfofBits | CFBit; 15799010Snilay@cs.wisc.edu } 15806601Sgblack@eecs.umich.edu else if(arg1 < arg2) 15819010Snilay@cs.wisc.edu cfofBits = cfofBits | CFBit; 15826601Sgblack@eecs.umich.edu else if(arg1 == arg2) 15836601Sgblack@eecs.umich.edu ccFlagBits = ccFlagBits | ZFBit; 15846601Sgblack@eecs.umich.edu ''' 15859471Snilay@cs.wisc.edu 15869471Snilay@cs.wisc.edu class Emms(MediaOp): 158712707Sgabeblack@google.com op_class = 'FloatMiscOp' 15889471Snilay@cs.wisc.edu def __init__(self): 15899471Snilay@cs.wisc.edu super(Emms, self).__init__('InstRegIndex(MISCREG_FTW)', 159010042Snilay@cs.wisc.edu 'InstRegIndex(0)', 'InstRegIndex(0)', 2) 15919471Snilay@cs.wisc.edu code = 'FTW = 0xFFFF;' 15926516Sgblack@eecs.umich.edu}}; 1593