mediaop.isa revision 6799:36131e4dfb6e
17202Sgblack@eecs.umich.edu/// Copyright (c) 2009 The Regents of The University of Michigan 27202Sgblack@eecs.umich.edu// All rights reserved. 312503Snikos.nikoleris@arm.com// 47202Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 57202Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 67202Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 77202Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 87202Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 97202Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 107202Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 117202Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 127202Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 137202Sgblack@eecs.umich.edu// this software without specific prior written permission. 147202Sgblack@eecs.umich.edu// 157202Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 167202Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 177202Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 187202Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 197202Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 207202Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 217202Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 227202Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 237202Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 247202Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 257202Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 267202Sgblack@eecs.umich.edu// 277202Sgblack@eecs.umich.edu// Authors: Gabe Black 287202Sgblack@eecs.umich.edu 297202Sgblack@eecs.umich.edudef template MediaOpExecute {{ 307202Sgblack@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 317202Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 327202Sgblack@eecs.umich.edu { 337202Sgblack@eecs.umich.edu Fault fault = NoFault; 347202Sgblack@eecs.umich.edu 357202Sgblack@eecs.umich.edu %(op_decl)s; 367202Sgblack@eecs.umich.edu %(op_rd)s; 377202Sgblack@eecs.umich.edu 387202Sgblack@eecs.umich.edu %(code)s; 397202Sgblack@eecs.umich.edu 407202Sgblack@eecs.umich.edu //Write the resulting state to the execution context 417202Sgblack@eecs.umich.edu if(fault == NoFault) 427202Sgblack@eecs.umich.edu { 437202Sgblack@eecs.umich.edu %(op_wb)s; 447202Sgblack@eecs.umich.edu } 457202Sgblack@eecs.umich.edu return fault; 467202Sgblack@eecs.umich.edu } 4712236Sgabeblack@google.com}}; 487202Sgblack@eecs.umich.edu 497202Sgblack@eecs.umich.edudef template MediaOpRegDeclare {{ 507202Sgblack@eecs.umich.edu class %(class_name)s : public %(base_class)s 517202Sgblack@eecs.umich.edu { 5210184SCurtis.Dunham@arm.com protected: 537202Sgblack@eecs.umich.edu void buildMe(); 547202Sgblack@eecs.umich.edu 557202Sgblack@eecs.umich.edu public: 567202Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst _machInst, 577848SAli.Saidi@ARM.com const char * instMnem, 587848SAli.Saidi@ARM.com bool isMicro, bool isDelayed, bool isFirst, bool isLast, 597848SAli.Saidi@ARM.com InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 607848SAli.Saidi@ARM.com uint8_t _srcSize, uint8_t _destSize, uint16_t _ext); 617848SAli.Saidi@ARM.com 627202Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst _machInst, 637202Sgblack@eecs.umich.edu const char * instMnem, 647202Sgblack@eecs.umich.edu InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 6510037SARM gem5 Developers uint8_t _srcSize, uint8_t _destSize, uint16_t _ext); 6610037SARM gem5 Developers 6710037SARM gem5 Developers %(BasicExecDeclare)s 6810037SARM gem5 Developers }; 6910037SARM gem5 Developers}}; 7010037SARM gem5 Developers 7110037SARM gem5 Developersdef template MediaOpImmDeclare {{ 7210037SARM gem5 Developers 7310037SARM gem5 Developers class %(class_name)s : public %(base_class)s 7410037SARM gem5 Developers { 7510037SARM gem5 Developers protected: 7612236Sgabeblack@google.com void buildMe(); 7710037SARM gem5 Developers 7810037SARM gem5 Developers public: 7910037SARM gem5 Developers %(class_name)s(ExtMachInst _machInst, 8010037SARM gem5 Developers const char * instMnem, 8110184SCurtis.Dunham@arm.com bool isMicro, bool isDelayed, bool isFirst, bool isLast, 8210037SARM gem5 Developers InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, 8310037SARM gem5 Developers uint8_t _srcSize, uint8_t _destSize, uint16_t _ext); 8410037SARM gem5 Developers 8510037SARM gem5 Developers %(class_name)s(ExtMachInst _machInst, 8610037SARM gem5 Developers const char * instMnem, 8710037SARM gem5 Developers InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, 8810037SARM gem5 Developers uint8_t _srcSize, uint8_t _destSize, uint16_t _ext); 8910037SARM gem5 Developers 9010037SARM gem5 Developers %(BasicExecDeclare)s 9110037SARM gem5 Developers }; 9210037SARM gem5 Developers}}; 9310037SARM gem5 Developers 9410037SARM gem5 Developersdef template MediaOpRegConstructor {{ 9510037SARM gem5 Developers 9610037SARM gem5 Developers inline void %(class_name)s::buildMe() 9710037SARM gem5 Developers { 9810037SARM gem5 Developers %(constructor)s; 9910037SARM gem5 Developers } 10010037SARM gem5 Developers 10110037SARM gem5 Developers inline %(class_name)s::%(class_name)s( 10210037SARM gem5 Developers ExtMachInst machInst, const char * instMnem, 10310037SARM gem5 Developers InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 10410037SARM gem5 Developers uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) : 10510037SARM gem5 Developers %(base_class)s(machInst, "%(mnemonic)s", instMnem, 10610037SARM gem5 Developers false, false, false, false, 10712236Sgabeblack@google.com _src1, _src2, _dest, _srcSize, _destSize, _ext, 10810037SARM gem5 Developers %(op_class)s) 10910037SARM gem5 Developers { 11010037SARM gem5 Developers buildMe(); 11110037SARM gem5 Developers } 11210184SCurtis.Dunham@arm.com 11310037SARM gem5 Developers inline %(class_name)s::%(class_name)s( 11410037SARM gem5 Developers ExtMachInst machInst, const char * instMnem, 11510037SARM gem5 Developers bool isMicro, bool isDelayed, bool isFirst, bool isLast, 11610037SARM gem5 Developers InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, 11710037SARM gem5 Developers uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) : 11810037SARM gem5 Developers %(base_class)s(machInst, "%(mnemonic)s", instMnem, 11910037SARM gem5 Developers isMicro, isDelayed, isFirst, isLast, 12010037SARM gem5 Developers _src1, _src2, _dest, _srcSize, _destSize, _ext, 12110037SARM gem5 Developers %(op_class)s) 12210037SARM gem5 Developers { 12310037SARM gem5 Developers buildMe(); 12410037SARM gem5 Developers } 12510037SARM gem5 Developers}}; 12610037SARM gem5 Developers 12710037SARM gem5 Developersdef template MediaOpImmConstructor {{ 1287202Sgblack@eecs.umich.edu 1297202Sgblack@eecs.umich.edu inline void %(class_name)s::buildMe() 1307202Sgblack@eecs.umich.edu { 1317202Sgblack@eecs.umich.edu %(constructor)s; 1327202Sgblack@eecs.umich.edu } 1337202Sgblack@eecs.umich.edu 1347202Sgblack@eecs.umich.edu inline %(class_name)s::%(class_name)s( 13512236Sgabeblack@google.com ExtMachInst machInst, const char * instMnem, 1367202Sgblack@eecs.umich.edu InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, 1377202Sgblack@eecs.umich.edu uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) : 1387202Sgblack@eecs.umich.edu %(base_class)s(machInst, "%(mnemonic)s", instMnem, 1397202Sgblack@eecs.umich.edu false, false, false, false, 14010184SCurtis.Dunham@arm.com _src1, _imm8, _dest, _srcSize, _destSize, _ext, 1417202Sgblack@eecs.umich.edu %(op_class)s) 1427202Sgblack@eecs.umich.edu { 1437202Sgblack@eecs.umich.edu buildMe(); 1447202Sgblack@eecs.umich.edu } 1457202Sgblack@eecs.umich.edu 1467848SAli.Saidi@ARM.com inline %(class_name)s::%(class_name)s( 1477848SAli.Saidi@ARM.com ExtMachInst machInst, const char * instMnem, 1487848SAli.Saidi@ARM.com bool isMicro, bool isDelayed, bool isFirst, bool isLast, 1497848SAli.Saidi@ARM.com InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, 1507848SAli.Saidi@ARM.com uint8_t _srcSize, uint8_t _destSize, uint16_t _ext) : 1517202Sgblack@eecs.umich.edu %(base_class)s(machInst, "%(mnemonic)s", instMnem, 1527202Sgblack@eecs.umich.edu isMicro, isDelayed, isFirst, isLast, 1537202Sgblack@eecs.umich.edu _src1, _imm8, _dest, _srcSize, _destSize, _ext, 1547202Sgblack@eecs.umich.edu %(op_class)s) 1557202Sgblack@eecs.umich.edu { 1567202Sgblack@eecs.umich.edu buildMe(); 1577202Sgblack@eecs.umich.edu } 1587202Sgblack@eecs.umich.edu}}; 1597202Sgblack@eecs.umich.edu 1607202Sgblack@eecs.umich.edulet {{ 16112236Sgabeblack@google.com # Make these empty strings so that concatenating onto 1627202Sgblack@eecs.umich.edu # them will always work. 1637202Sgblack@eecs.umich.edu header_output = "" 1647202Sgblack@eecs.umich.edu decoder_output = "" 1657202Sgblack@eecs.umich.edu exec_output = "" 16610184SCurtis.Dunham@arm.com 1677202Sgblack@eecs.umich.edu immTemplates = ( 1687202Sgblack@eecs.umich.edu MediaOpImmDeclare, 1697202Sgblack@eecs.umich.edu MediaOpImmConstructor, 1707202Sgblack@eecs.umich.edu MediaOpExecute) 1717202Sgblack@eecs.umich.edu 1727848SAli.Saidi@ARM.com regTemplates = ( 1737848SAli.Saidi@ARM.com MediaOpRegDeclare, 1747848SAli.Saidi@ARM.com MediaOpRegConstructor, 1757848SAli.Saidi@ARM.com MediaOpExecute) 1767848SAli.Saidi@ARM.com 1777202Sgblack@eecs.umich.edu class MediaOpMeta(type): 1787202Sgblack@eecs.umich.edu def buildCppClasses(self, name, Name, suffix, code): 1797208Sgblack@eecs.umich.edu 18010037SARM gem5 Developers # Globals to stick the output in 18110037SARM gem5 Developers global header_output 18210037SARM gem5 Developers global decoder_output 18310037SARM gem5 Developers global exec_output 18410037SARM gem5 Developers 18510037SARM gem5 Developers # If op2 is used anywhere, make register and immediate versions 18610420Sandreas.hansson@arm.com # of this code. 18710037SARM gem5 Developers matcher = re.compile("(?<!\\w)(?P<prefix>s?)op2(?P<typeQual>\\.\\w+)?") 18812236Sgabeblack@google.com match = matcher.search(code) 18910037SARM gem5 Developers if match: 19010037SARM gem5 Developers typeQual = "" 19110037SARM gem5 Developers if match.group("typeQual"): 19210037SARM gem5 Developers typeQual = match.group("typeQual") 19310184SCurtis.Dunham@arm.com src2_name = "%sFpSrcReg2%s" % (match.group("prefix"), typeQual) 19410420Sandreas.hansson@arm.com self.buildCppClasses(name, Name, suffix, 19510037SARM gem5 Developers matcher.sub(src2_name, code)) 19610037SARM gem5 Developers self.buildCppClasses(name + "i", Name, suffix + "Imm", 19710037SARM gem5 Developers matcher.sub("imm8", code)) 19810037SARM gem5 Developers return 19910037SARM gem5 Developers 20010037SARM gem5 Developers base = "X86ISA::MediaOp" 20110037SARM gem5 Developers 20210037SARM gem5 Developers # If imm8 shows up in the code, use the immediate templates, if 20310037SARM gem5 Developers # not, hopefully the register ones will be correct. 20410037SARM gem5 Developers matcher = re.compile("(?<!\w)imm8(?!\w)") 20510037SARM gem5 Developers if matcher.search(code): 20610037SARM gem5 Developers base += "Imm" 20710037SARM gem5 Developers templates = immTemplates 20810037SARM gem5 Developers else: 20910037SARM gem5 Developers base += "Reg" 21010037SARM gem5 Developers templates = regTemplates 21110037SARM gem5 Developers 21210037SARM gem5 Developers # Get everything ready for the substitution 21310037SARM gem5 Developers iop = InstObjParams(name, Name + suffix, base, {"code" : code}) 21410037SARM gem5 Developers 21510037SARM gem5 Developers # Generate the actual code (finally!) 21610037SARM gem5 Developers header_output += templates[0].subst(iop) 21710420Sandreas.hansson@arm.com decoder_output += templates[1].subst(iop) 21812236Sgabeblack@google.com exec_output += templates[2].subst(iop) 21910037SARM gem5 Developers 22010037SARM gem5 Developers 22110037SARM gem5 Developers def __new__(mcls, Name, bases, dict): 22210037SARM gem5 Developers abstract = False 22310184SCurtis.Dunham@arm.com name = Name.lower() 22410037SARM gem5 Developers if "abstract" in dict: 22510037SARM gem5 Developers abstract = dict['abstract'] 22610420Sandreas.hansson@arm.com del dict['abstract'] 22710037SARM gem5 Developers 22810037SARM gem5 Developers cls = super(MediaOpMeta, mcls).__new__(mcls, Name, bases, dict) 22910037SARM gem5 Developers if not abstract: 23010037SARM gem5 Developers cls.className = Name 23110037SARM gem5 Developers cls.base_mnemonic = name 23210037SARM gem5 Developers code = cls.code 23310037SARM gem5 Developers 23410037SARM gem5 Developers # Set up the C++ classes 23510037SARM gem5 Developers mcls.buildCppClasses(cls, name, Name, "", code) 23610037SARM gem5 Developers 23710037SARM gem5 Developers # Hook into the microassembler dict 23810037SARM gem5 Developers global microopClasses 23910037SARM gem5 Developers microopClasses[name] = cls 2407306Sgblack@eecs.umich.edu 2417306Sgblack@eecs.umich.edu # If op2 is used anywhere, make register and immediate versions 2427306Sgblack@eecs.umich.edu # of this code. 2437306Sgblack@eecs.umich.edu matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 2447306Sgblack@eecs.umich.edu if matcher.search(code): 2457306Sgblack@eecs.umich.edu microopClasses[name + 'i'] = cls 2467330Sgblack@eecs.umich.edu return cls 24712236Sgabeblack@google.com 2487306Sgblack@eecs.umich.edu 2497306Sgblack@eecs.umich.edu class MediaOp(X86Microop): 2507306Sgblack@eecs.umich.edu __metaclass__ = MediaOpMeta 2517306Sgblack@eecs.umich.edu # This class itself doesn't act as a microop 25210184SCurtis.Dunham@arm.com abstract = True 2537306Sgblack@eecs.umich.edu 2547306Sgblack@eecs.umich.edu def __init__(self, dest, src1, op2, 2557306Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 2567848SAli.Saidi@ARM.com self.dest = dest 2577848SAli.Saidi@ARM.com self.src1 = src1 2587848SAli.Saidi@ARM.com self.op2 = op2 2597848SAli.Saidi@ARM.com if size is not None: 2607848SAli.Saidi@ARM.com self.srcSize = size 2617306Sgblack@eecs.umich.edu self.destSize = size 2627306Sgblack@eecs.umich.edu if srcSize is not None: 2637306Sgblack@eecs.umich.edu self.srcSize = srcSize 2647332Sgblack@eecs.umich.edu if destSize is not None: 2657332Sgblack@eecs.umich.edu self.destSize = destSize 2667332Sgblack@eecs.umich.edu if self.srcSize is None: 2677332Sgblack@eecs.umich.edu raise Exception, "Source size not set." 2687332Sgblack@eecs.umich.edu if self.destSize is None: 2697332Sgblack@eecs.umich.edu raise Exception, "Dest size not set." 2707332Sgblack@eecs.umich.edu if ext is None: 27112236Sgabeblack@google.com self.ext = 0 2727332Sgblack@eecs.umich.edu else: 2737332Sgblack@eecs.umich.edu self.ext = ext 2747332Sgblack@eecs.umich.edu 2757332Sgblack@eecs.umich.edu def getAllocator(self, *microFlags): 27610184SCurtis.Dunham@arm.com className = self.className 2777332Sgblack@eecs.umich.edu if self.mnemonic == self.base_mnemonic + 'i': 2787332Sgblack@eecs.umich.edu className += "Imm" 2797332Sgblack@eecs.umich.edu allocator = '''new %(class_name)s(machInst, macrocodeBlock 2807332Sgblack@eecs.umich.edu %(flags)s, %(src1)s, %(op2)s, %(dest)s, 2817848SAli.Saidi@ARM.com %(srcSize)s, %(destSize)s, %(ext)s)''' % { 2827848SAli.Saidi@ARM.com "class_name" : className, 2837848SAli.Saidi@ARM.com "flags" : self.microFlagsText(microFlags), 2847848SAli.Saidi@ARM.com "src1" : self.src1, "op2" : self.op2, 2857848SAli.Saidi@ARM.com "dest" : self.dest, 2867332Sgblack@eecs.umich.edu "srcSize" : self.srcSize, 2877332Sgblack@eecs.umich.edu "destSize" : self.destSize, 2887332Sgblack@eecs.umich.edu "ext" : self.ext} 2897261Sgblack@eecs.umich.edu return allocator 2907208Sgblack@eecs.umich.edu 2917208Sgblack@eecs.umich.edu class Mov2int(MediaOp): 2927208Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2 = 0, \ 2937208Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 2947208Sgblack@eecs.umich.edu super(Mov2int, self).__init__(dest, src1,\ 2957208Sgblack@eecs.umich.edu src2, size, destSize, srcSize, ext) 2967208Sgblack@eecs.umich.edu code = ''' 29712236Sgabeblack@google.com int items = sizeof(FloatRegBits) / srcSize; 2987208Sgblack@eecs.umich.edu int offset = imm8; 2997208Sgblack@eecs.umich.edu if (bits(src1, 0) && (ext & 0x1)) 3007208Sgblack@eecs.umich.edu offset -= items; 3017261Sgblack@eecs.umich.edu if (offset >= 0 && offset < items) { 30210184SCurtis.Dunham@arm.com uint64_t fpSrcReg1 = 3037208Sgblack@eecs.umich.edu bits(FpSrcReg1.uqw, 3047208Sgblack@eecs.umich.edu (offset + 1) * srcSize * 8 - 1, 3057208Sgblack@eecs.umich.edu (offset + 0) * srcSize * 8); 3067208Sgblack@eecs.umich.edu DestReg = merge(0, fpSrcReg1, destSize); 3077848SAli.Saidi@ARM.com } else { 3087848SAli.Saidi@ARM.com DestReg = DestReg; 3097848SAli.Saidi@ARM.com } 3107848SAli.Saidi@ARM.com ''' 3117848SAli.Saidi@ARM.com 3127208Sgblack@eecs.umich.edu class Mov2fp(MediaOp): 3137208Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2 = 0, \ 3147225Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 3157233Sgblack@eecs.umich.edu super(Mov2fp, self).__init__(dest, src1,\ 3167233Sgblack@eecs.umich.edu src2, size, destSize, srcSize, ext) 3177233Sgblack@eecs.umich.edu code = ''' 3187233Sgblack@eecs.umich.edu int items = sizeof(FloatRegBits) / destSize; 3197233Sgblack@eecs.umich.edu int offset = imm8; 3207233Sgblack@eecs.umich.edu if (bits(dest, 0) && (ext & 0x1)) 3217233Sgblack@eecs.umich.edu offset -= items; 3227233Sgblack@eecs.umich.edu if (offset >= 0 && offset < items) { 3237330Sgblack@eecs.umich.edu uint64_t srcReg1 = pick(SrcReg1, 0, srcSize); 32412236Sgabeblack@google.com FpDestReg.uqw = 3257233Sgblack@eecs.umich.edu insertBits(FpDestReg.uqw, 3267233Sgblack@eecs.umich.edu (offset + 1) * destSize * 8 - 1, 3277233Sgblack@eecs.umich.edu (offset + 0) * destSize * 8, srcReg1); 3287233Sgblack@eecs.umich.edu } else { 32910184SCurtis.Dunham@arm.com FpDestReg.uqw = FpDestReg.uqw; 3307233Sgblack@eecs.umich.edu } 3317233Sgblack@eecs.umich.edu ''' 3327233Sgblack@eecs.umich.edu 3337330Sgblack@eecs.umich.edu class Movsign(MediaOp): 3347233Sgblack@eecs.umich.edu def __init__(self, dest, src, \ 3357233Sgblack@eecs.umich.edu size = None, destSize = None, srcSize = None, ext = None): 3367233Sgblack@eecs.umich.edu super(Movsign, self).__init__(dest, src,\ 3377233Sgblack@eecs.umich.edu "InstRegIndex(0)", size, destSize, srcSize, ext) 3387848SAli.Saidi@ARM.com code = ''' 3397848SAli.Saidi@ARM.com int items = sizeof(FloatRegBits) / srcSize; 3407848SAli.Saidi@ARM.com uint64_t result = 0; 3417848SAli.Saidi@ARM.com int offset = (ext & 0x1) ? items : 0; 3427848SAli.Saidi@ARM.com for (int i = 0; i < items; i++) { 3437233Sgblack@eecs.umich.edu uint64_t picked = 3447233Sgblack@eecs.umich.edu bits(FpSrcReg1.uqw, (i + 1) * 8 * srcSize - 1); 3457233Sgblack@eecs.umich.edu result = insertBits(result, i + offset, i + offset, picked); 3467241Sgblack@eecs.umich.edu } 3477241Sgblack@eecs.umich.edu DestReg = DestReg | result; 3487241Sgblack@eecs.umich.edu ''' 3497241Sgblack@eecs.umich.edu 3507241Sgblack@eecs.umich.edu class Maskmov(MediaOp): 3517241Sgblack@eecs.umich.edu code = ''' 3527241Sgblack@eecs.umich.edu assert(srcSize == destSize); 3537241Sgblack@eecs.umich.edu int size = srcSize; 3547241Sgblack@eecs.umich.edu int sizeBits = size * 8; 35512236Sgabeblack@google.com int items = numItems(size); 3567241Sgblack@eecs.umich.edu uint64_t result = FpDestReg.uqw; 3577241Sgblack@eecs.umich.edu 3587241Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 3597241Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 36010184SCurtis.Dunham@arm.com int loIndex = (i + 0) * sizeBits; 3617241Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 3627241Sgblack@eecs.umich.edu if (bits(FpSrcReg2.uqw, hiIndex)) 3637241Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, arg1Bits); 3647241Sgblack@eecs.umich.edu } 3657241Sgblack@eecs.umich.edu FpDestReg.uqw = result; 3667241Sgblack@eecs.umich.edu ''' 3677241Sgblack@eecs.umich.edu 3687241Sgblack@eecs.umich.edu class shuffle(MediaOp): 3697848SAli.Saidi@ARM.com code = ''' 3707848SAli.Saidi@ARM.com assert(srcSize == destSize); 3717848SAli.Saidi@ARM.com int size = srcSize; 3727848SAli.Saidi@ARM.com int sizeBits = size * 8; 3737848SAli.Saidi@ARM.com int items = sizeof(FloatRegBits) / size; 3747241Sgblack@eecs.umich.edu int options; 3757241Sgblack@eecs.umich.edu int optionBits; 3767241Sgblack@eecs.umich.edu if (size == 8) { 3777238Sgblack@eecs.umich.edu options = 2; 3787238Sgblack@eecs.umich.edu optionBits = 1; 3797238Sgblack@eecs.umich.edu } else { 3807238Sgblack@eecs.umich.edu options = 4; 3817238Sgblack@eecs.umich.edu optionBits = 2; 3827238Sgblack@eecs.umich.edu } 3837238Sgblack@eecs.umich.edu 3847238Sgblack@eecs.umich.edu uint64_t result = 0; 38512236Sgabeblack@google.com uint8_t sel = ext; 3867238Sgblack@eecs.umich.edu 3877238Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 3887238Sgblack@eecs.umich.edu uint64_t resBits; 3897238Sgblack@eecs.umich.edu uint8_t lsel = sel & mask(optionBits); 39010184SCurtis.Dunham@arm.com if (lsel * size >= sizeof(FloatRegBits)) { 3917238Sgblack@eecs.umich.edu lsel -= options / 2; 3927238Sgblack@eecs.umich.edu resBits = bits(FpSrcReg2.uqw, 3937238Sgblack@eecs.umich.edu (lsel + 1) * sizeBits - 1, 3947238Sgblack@eecs.umich.edu (lsel + 0) * sizeBits); 3957238Sgblack@eecs.umich.edu } else { 3967238Sgblack@eecs.umich.edu resBits = bits(FpSrcReg1.uqw, 3977238Sgblack@eecs.umich.edu (lsel + 1) * sizeBits - 1, 3987848SAli.Saidi@ARM.com (lsel + 0) * sizeBits); 3997848SAli.Saidi@ARM.com } 4007848SAli.Saidi@ARM.com 4017848SAli.Saidi@ARM.com sel >>= optionBits; 4027848SAli.Saidi@ARM.com 4037238Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 4047238Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 4057238Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, resBits); 4067331Sgblack@eecs.umich.edu } 4077331Sgblack@eecs.umich.edu FpDestReg.uqw = result; 4087331Sgblack@eecs.umich.edu ''' 4097331Sgblack@eecs.umich.edu 4107331Sgblack@eecs.umich.edu class Unpack(MediaOp): 4117331Sgblack@eecs.umich.edu code = ''' 4127331Sgblack@eecs.umich.edu assert(srcSize == destSize); 4137331Sgblack@eecs.umich.edu int size = destSize; 4147331Sgblack@eecs.umich.edu int items = (sizeof(FloatRegBits) / size) / 2; 41512236Sgabeblack@google.com int offset = ext ? items : 0; 4167331Sgblack@eecs.umich.edu uint64_t result = 0; 4177331Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 4187331Sgblack@eecs.umich.edu uint64_t pickedLow = 4197331Sgblack@eecs.umich.edu bits(FpSrcReg1.uqw, (i + offset + 1) * 8 * size - 1, 42010184SCurtis.Dunham@arm.com (i + offset) * 8 * size); 4217331Sgblack@eecs.umich.edu result = insertBits(result, 4227331Sgblack@eecs.umich.edu (2 * i + 1) * 8 * size - 1, 4237331Sgblack@eecs.umich.edu (2 * i + 0) * 8 * size, 4247331Sgblack@eecs.umich.edu pickedLow); 4257331Sgblack@eecs.umich.edu uint64_t pickedHigh = 4267331Sgblack@eecs.umich.edu bits(FpSrcReg2.uqw, (i + offset + 1) * 8 * size - 1, 4277331Sgblack@eecs.umich.edu (i + offset) * 8 * size); 4287848SAli.Saidi@ARM.com result = insertBits(result, 4297848SAli.Saidi@ARM.com (2 * i + 2) * 8 * size - 1, 4307848SAli.Saidi@ARM.com (2 * i + 1) * 8 * size, 4317848SAli.Saidi@ARM.com pickedHigh); 4327848SAli.Saidi@ARM.com } 4337331Sgblack@eecs.umich.edu FpDestReg.uqw = result; 4347331Sgblack@eecs.umich.edu ''' 4357331Sgblack@eecs.umich.edu 43610418Sandreas.hansson@arm.com class Pack(MediaOp): 43710418Sandreas.hansson@arm.com code = ''' 43810418Sandreas.hansson@arm.com assert(srcSize == destSize * 2); 43910418Sandreas.hansson@arm.com int items = (sizeof(FloatRegBits) / destSize); 44010418Sandreas.hansson@arm.com int destBits = destSize * 8; 44110418Sandreas.hansson@arm.com int srcBits = srcSize * 8; 44210418Sandreas.hansson@arm.com uint64_t result = 0; 44310418Sandreas.hansson@arm.com int i; 44410418Sandreas.hansson@arm.com for (i = 0; i < items / 2; i++) { 44512236Sgabeblack@google.com uint64_t picked = 44610418Sandreas.hansson@arm.com bits(FpSrcReg1.uqw, (i + 1) * srcBits - 1, 44710418Sandreas.hansson@arm.com (i + 0) * srcBits); 44810418Sandreas.hansson@arm.com unsigned signBit = bits(picked, srcBits - 1); 44910418Sandreas.hansson@arm.com uint64_t overflow = bits(picked, srcBits - 1, destBits - 1); 45010418Sandreas.hansson@arm.com 45110418Sandreas.hansson@arm.com // Handle saturation. 45210418Sandreas.hansson@arm.com if (signBit) { 45310418Sandreas.hansson@arm.com if (overflow != mask(destBits - srcBits + 1)) { 45410418Sandreas.hansson@arm.com if (ext & 0x1) 45510418Sandreas.hansson@arm.com picked = (ULL(1) << (destBits - 1)); 45610418Sandreas.hansson@arm.com else 45710418Sandreas.hansson@arm.com picked = 0; 45810418Sandreas.hansson@arm.com } 45910418Sandreas.hansson@arm.com } else { 46010418Sandreas.hansson@arm.com if (overflow != 0) { 46110418Sandreas.hansson@arm.com if (ext & 0x1) 46210418Sandreas.hansson@arm.com picked = mask(destBits - 1); 46310418Sandreas.hansson@arm.com else 46410418Sandreas.hansson@arm.com picked = mask(destBits); 46510418Sandreas.hansson@arm.com } 46610418Sandreas.hansson@arm.com } 46710418Sandreas.hansson@arm.com result = insertBits(result, 46810418Sandreas.hansson@arm.com (i + 1) * destBits - 1, 46910418Sandreas.hansson@arm.com (i + 0) * destBits, 47010418Sandreas.hansson@arm.com picked); 47110418Sandreas.hansson@arm.com } 47210418Sandreas.hansson@arm.com for (;i < items; i++) { 47310418Sandreas.hansson@arm.com uint64_t picked = 47410418Sandreas.hansson@arm.com bits(FpSrcReg2.uqw, (i - items + 1) * srcBits - 1, 47512236Sgabeblack@google.com (i - items + 0) * srcBits); 47610418Sandreas.hansson@arm.com unsigned signBit = bits(picked, srcBits - 1); 47710418Sandreas.hansson@arm.com uint64_t overflow = bits(picked, srcBits - 1, destBits - 1); 47810418Sandreas.hansson@arm.com 47910418Sandreas.hansson@arm.com // Handle saturation. 48010418Sandreas.hansson@arm.com if (signBit) { 48110418Sandreas.hansson@arm.com if (overflow != mask(destBits - srcBits + 1)) { 48210418Sandreas.hansson@arm.com if (ext & 0x1) 48310418Sandreas.hansson@arm.com picked = (ULL(1) << (destBits - 1)); 48410418Sandreas.hansson@arm.com else 48510418Sandreas.hansson@arm.com picked = 0; 48610418Sandreas.hansson@arm.com } 48710418Sandreas.hansson@arm.com } else { 48810418Sandreas.hansson@arm.com if (overflow != 0) { 48910418Sandreas.hansson@arm.com if (ext & 0x1) 49010418Sandreas.hansson@arm.com picked = mask(destBits - 1); 49110418Sandreas.hansson@arm.com else 49210418Sandreas.hansson@arm.com picked = mask(destBits); 49310418Sandreas.hansson@arm.com } 49410418Sandreas.hansson@arm.com } 49510418Sandreas.hansson@arm.com result = insertBits(result, 49610037SARM gem5 Developers (i + 1) * destBits - 1, 49710037SARM gem5 Developers (i + 0) * destBits, 49810037SARM gem5 Developers picked); 49910037SARM gem5 Developers } 50010037SARM gem5 Developers FpDestReg.uqw = result; 50110037SARM gem5 Developers ''' 50210037SARM gem5 Developers 50310037SARM gem5 Developers class Mxor(MediaOp): 50412236Sgabeblack@google.com def __init__(self, dest, src1, src2): 50510037SARM gem5 Developers super(Mxor, self).__init__(dest, src1, src2, 1) 50610037SARM gem5 Developers code = ''' 50710037SARM gem5 Developers FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw; 50810037SARM gem5 Developers ''' 50910184SCurtis.Dunham@arm.com 51010037SARM gem5 Developers class Mor(MediaOp): 51110037SARM gem5 Developers def __init__(self, dest, src1, src2): 51210037SARM gem5 Developers super(Mor, self).__init__(dest, src1, src2, 1) 51310037SARM gem5 Developers code = ''' 51410037SARM gem5 Developers FpDestReg.uqw = FpSrcReg1.uqw | FpSrcReg2.uqw; 51510037SARM gem5 Developers ''' 51610037SARM gem5 Developers 51710037SARM gem5 Developers class Mand(MediaOp): 51810037SARM gem5 Developers def __init__(self, dest, src1, src2): 51910037SARM gem5 Developers super(Mand, self).__init__(dest, src1, src2, 1) 52010037SARM gem5 Developers code = ''' 52110037SARM gem5 Developers FpDestReg.uqw = FpSrcReg1.uqw & FpSrcReg2.uqw; 52210037SARM gem5 Developers ''' 52310037SARM gem5 Developers 52410037SARM gem5 Developers class Mandn(MediaOp): 5257253Sgblack@eecs.umich.edu def __init__(self, dest, src1, src2): 5267253Sgblack@eecs.umich.edu super(Mandn, self).__init__(dest, src1, src2, 1) 5277253Sgblack@eecs.umich.edu code = ''' 5287253Sgblack@eecs.umich.edu FpDestReg.uqw = ~FpSrcReg1.uqw & FpSrcReg2.uqw; 5297253Sgblack@eecs.umich.edu ''' 5307253Sgblack@eecs.umich.edu 5317253Sgblack@eecs.umich.edu class Mminf(MediaOp): 5327253Sgblack@eecs.umich.edu code = ''' 5337330Sgblack@eecs.umich.edu union floatInt 53412236Sgabeblack@google.com { 5357253Sgblack@eecs.umich.edu float f; 5367253Sgblack@eecs.umich.edu uint32_t i; 5377253Sgblack@eecs.umich.edu }; 5387253Sgblack@eecs.umich.edu union doubleInt 53910184SCurtis.Dunham@arm.com { 5407253Sgblack@eecs.umich.edu double d; 5417253Sgblack@eecs.umich.edu uint64_t i; 5427330Sgblack@eecs.umich.edu }; 5437330Sgblack@eecs.umich.edu 5447253Sgblack@eecs.umich.edu assert(srcSize == destSize); 5457253Sgblack@eecs.umich.edu int size = srcSize; 5467253Sgblack@eecs.umich.edu int sizeBits = size * 8; 5477253Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 5487848SAli.Saidi@ARM.com int items = numItems(size); 5497848SAli.Saidi@ARM.com uint64_t result = FpDestReg.uqw; 5507848SAli.Saidi@ARM.com 5517848SAli.Saidi@ARM.com for (int i = 0; i < items; i++) { 5527848SAli.Saidi@ARM.com double arg1, arg2; 5537253Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 5547253Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 5557253Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 5567232Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 5577225Sgblack@eecs.umich.edu 5587225Sgblack@eecs.umich.edu if (size == 4) { 5597225Sgblack@eecs.umich.edu floatInt fi; 5607225Sgblack@eecs.umich.edu fi.i = arg1Bits; 5617225Sgblack@eecs.umich.edu arg1 = fi.f; 5627225Sgblack@eecs.umich.edu fi.i = arg2Bits; 5637330Sgblack@eecs.umich.edu arg2 = fi.f; 56412236Sgabeblack@google.com } else { 5657225Sgblack@eecs.umich.edu doubleInt di; 5667225Sgblack@eecs.umich.edu di.i = arg1Bits; 5677225Sgblack@eecs.umich.edu arg1 = di.d; 5687232Sgblack@eecs.umich.edu di.i = arg2Bits; 56910184SCurtis.Dunham@arm.com arg2 = di.d; 5707225Sgblack@eecs.umich.edu } 5717330Sgblack@eecs.umich.edu 5727225Sgblack@eecs.umich.edu if (arg1 < arg2) { 5737225Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, arg1Bits); 5747232Sgblack@eecs.umich.edu } else { 5757225Sgblack@eecs.umich.edu result = insertBits(result, hiIndex, loIndex, arg2Bits); 5767225Sgblack@eecs.umich.edu } 5777848SAli.Saidi@ARM.com } 5787848SAli.Saidi@ARM.com FpDestReg.uqw = result; 5797848SAli.Saidi@ARM.com ''' 5807848SAli.Saidi@ARM.com 5817848SAli.Saidi@ARM.com class Mmaxf(MediaOp): 5827225Sgblack@eecs.umich.edu code = ''' 5837225Sgblack@eecs.umich.edu union floatInt 5847225Sgblack@eecs.umich.edu { 5857232Sgblack@eecs.umich.edu float f; 5867225Sgblack@eecs.umich.edu uint32_t i; 5877225Sgblack@eecs.umich.edu }; 5887225Sgblack@eecs.umich.edu union doubleInt 5897225Sgblack@eecs.umich.edu { 5907225Sgblack@eecs.umich.edu double d; 5917225Sgblack@eecs.umich.edu uint64_t i; 5927330Sgblack@eecs.umich.edu }; 5937225Sgblack@eecs.umich.edu 59412236Sgabeblack@google.com assert(srcSize == destSize); 5957225Sgblack@eecs.umich.edu int size = srcSize; 5967225Sgblack@eecs.umich.edu int sizeBits = size * 8; 5977225Sgblack@eecs.umich.edu assert(srcSize == 4 || srcSize == 8); 5987232Sgblack@eecs.umich.edu int items = numItems(size); 59910184SCurtis.Dunham@arm.com uint64_t result = FpDestReg.uqw; 6007225Sgblack@eecs.umich.edu 6017330Sgblack@eecs.umich.edu for (int i = 0; i < items; i++) { 6027225Sgblack@eecs.umich.edu double arg1, arg2; 6037225Sgblack@eecs.umich.edu int hiIndex = (i + 1) * sizeBits - 1; 6047225Sgblack@eecs.umich.edu int loIndex = (i + 0) * sizeBits; 6057225Sgblack@eecs.umich.edu uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 6067232Sgblack@eecs.umich.edu uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 6077225Sgblack@eecs.umich.edu 6087225Sgblack@eecs.umich.edu if (size == 4) { 6097848SAli.Saidi@ARM.com floatInt fi; 6107848SAli.Saidi@ARM.com fi.i = arg1Bits; 6117848SAli.Saidi@ARM.com arg1 = fi.f; 6127848SAli.Saidi@ARM.com fi.i = arg2Bits; 6137848SAli.Saidi@ARM.com arg2 = fi.f; 6147225Sgblack@eecs.umich.edu } else { 6157225Sgblack@eecs.umich.edu doubleInt di; 6167609SGene.Wu@arm.com di.i = arg1Bits; 61712358Snikos.nikoleris@arm.com arg1 = di.d; 61812358Snikos.nikoleris@arm.com di.i = arg2Bits; 61912358Snikos.nikoleris@arm.com arg2 = di.d; 62012358Snikos.nikoleris@arm.com } 62112358Snikos.nikoleris@arm.com 62212358Snikos.nikoleris@arm.com if (arg1 > arg2) { 62312358Snikos.nikoleris@arm.com result = insertBits(result, hiIndex, loIndex, arg1Bits); 62412358Snikos.nikoleris@arm.com } else { 62512358Snikos.nikoleris@arm.com result = insertBits(result, hiIndex, loIndex, arg2Bits); 62612358Snikos.nikoleris@arm.com } 62712358Snikos.nikoleris@arm.com } 62812358Snikos.nikoleris@arm.com FpDestReg.uqw = result; 62912358Snikos.nikoleris@arm.com ''' 63012358Snikos.nikoleris@arm.com 63112358Snikos.nikoleris@arm.com class Mmini(MediaOp): 63212358Snikos.nikoleris@arm.com code = ''' 63312358Snikos.nikoleris@arm.com 63412358Snikos.nikoleris@arm.com assert(srcSize == destSize); 63512358Snikos.nikoleris@arm.com int size = srcSize; 63612358Snikos.nikoleris@arm.com int sizeBits = size * 8; 63712358Snikos.nikoleris@arm.com int items = numItems(size); 63812358Snikos.nikoleris@arm.com uint64_t result = FpDestReg.uqw; 63912358Snikos.nikoleris@arm.com 64012358Snikos.nikoleris@arm.com for (int i = 0; i < items; i++) { 64112358Snikos.nikoleris@arm.com int hiIndex = (i + 1) * sizeBits - 1; 64212358Snikos.nikoleris@arm.com int loIndex = (i + 0) * sizeBits; 64312358Snikos.nikoleris@arm.com uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 64412358Snikos.nikoleris@arm.com int64_t arg1 = arg1Bits | 64512358Snikos.nikoleris@arm.com (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); 64612358Snikos.nikoleris@arm.com uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 64712358Snikos.nikoleris@arm.com int64_t arg2 = arg2Bits | 64812358Snikos.nikoleris@arm.com (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); 64912503Snikos.nikoleris@arm.com uint64_t resBits; 65012503Snikos.nikoleris@arm.com 65112503Snikos.nikoleris@arm.com if (ext & 0x2) { 65212358Snikos.nikoleris@arm.com if (arg1 < arg2) { 65312358Snikos.nikoleris@arm.com resBits = arg1Bits; 65412358Snikos.nikoleris@arm.com } else { 65512358Snikos.nikoleris@arm.com resBits = arg2Bits; 65612358Snikos.nikoleris@arm.com } 65712358Snikos.nikoleris@arm.com } else { 65812358Snikos.nikoleris@arm.com if (arg1Bits < arg2Bits) { 65912358Snikos.nikoleris@arm.com resBits = arg1Bits; 66012358Snikos.nikoleris@arm.com } else { 66112358Snikos.nikoleris@arm.com resBits = arg2Bits; 66212358Snikos.nikoleris@arm.com } 66312358Snikos.nikoleris@arm.com } 66412358Snikos.nikoleris@arm.com result = insertBits(result, hiIndex, loIndex, resBits); 66512358Snikos.nikoleris@arm.com } 66612358Snikos.nikoleris@arm.com FpDestReg.uqw = result; 66712358Snikos.nikoleris@arm.com ''' 66812358Snikos.nikoleris@arm.com 66912358Snikos.nikoleris@arm.com class Mmaxi(MediaOp): 67012358Snikos.nikoleris@arm.com code = ''' 67112358Snikos.nikoleris@arm.com 67212358Snikos.nikoleris@arm.com assert(srcSize == destSize); 67312358Snikos.nikoleris@arm.com int size = srcSize; 67412358Snikos.nikoleris@arm.com int sizeBits = size * 8; 67512358Snikos.nikoleris@arm.com int items = numItems(size); 67612358Snikos.nikoleris@arm.com uint64_t result = FpDestReg.uqw; 67712358Snikos.nikoleris@arm.com 67812503Snikos.nikoleris@arm.com for (int i = 0; i < items; i++) { 67912503Snikos.nikoleris@arm.com int hiIndex = (i + 1) * sizeBits - 1; 68012503Snikos.nikoleris@arm.com int loIndex = (i + 0) * sizeBits; 68112358Snikos.nikoleris@arm.com uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 68212358Snikos.nikoleris@arm.com int64_t arg1 = arg1Bits | 68312358Snikos.nikoleris@arm.com (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); 68412358Snikos.nikoleris@arm.com uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 68512358Snikos.nikoleris@arm.com int64_t arg2 = arg2Bits | 68612358Snikos.nikoleris@arm.com (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); 68712358Snikos.nikoleris@arm.com uint64_t resBits; 68812358Snikos.nikoleris@arm.com 68912358Snikos.nikoleris@arm.com if (ext & 0x2) { 69012358Snikos.nikoleris@arm.com if (arg1 > arg2) { 69112358Snikos.nikoleris@arm.com resBits = arg1Bits; 69212358Snikos.nikoleris@arm.com } else { 69312358Snikos.nikoleris@arm.com resBits = arg2Bits; 69412358Snikos.nikoleris@arm.com } 69512358Snikos.nikoleris@arm.com } else { 69612358Snikos.nikoleris@arm.com if (arg1Bits > arg2Bits) { 69712358Snikos.nikoleris@arm.com resBits = arg1Bits; 698 } else { 699 resBits = arg2Bits; 700 } 701 } 702 result = insertBits(result, hiIndex, loIndex, resBits); 703 } 704 FpDestReg.uqw = result; 705 ''' 706 707 class Msqrt(MediaOp): 708 def __init__(self, dest, src, \ 709 size = None, destSize = None, srcSize = None, ext = None): 710 super(Msqrt, self).__init__(dest, src,\ 711 "InstRegIndex(0)", size, destSize, srcSize, ext) 712 code = ''' 713 union floatInt 714 { 715 float f; 716 uint32_t i; 717 }; 718 union doubleInt 719 { 720 double d; 721 uint64_t i; 722 }; 723 724 assert(srcSize == destSize); 725 int size = srcSize; 726 int sizeBits = size * 8; 727 assert(srcSize == 4 || srcSize == 8); 728 int items = numItems(size); 729 uint64_t result = FpDestReg.uqw; 730 731 for (int i = 0; i < items; i++) { 732 int hiIndex = (i + 1) * sizeBits - 1; 733 int loIndex = (i + 0) * sizeBits; 734 uint64_t argBits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 735 736 if (size == 4) { 737 floatInt fi; 738 fi.i = argBits; 739 fi.f = sqrt(fi.f); 740 argBits = fi.i; 741 } else { 742 doubleInt di; 743 di.i = argBits; 744 di.d = sqrt(di.d); 745 argBits = di.i; 746 } 747 result = insertBits(result, hiIndex, loIndex, argBits); 748 } 749 FpDestReg.uqw = result; 750 ''' 751 752 class Maddf(MediaOp): 753 code = ''' 754 union floatInt 755 { 756 float f; 757 uint32_t i; 758 }; 759 union doubleInt 760 { 761 double d; 762 uint64_t i; 763 }; 764 765 assert(srcSize == destSize); 766 int size = srcSize; 767 int sizeBits = size * 8; 768 assert(srcSize == 4 || srcSize == 8); 769 int items = numItems(size); 770 uint64_t result = FpDestReg.uqw; 771 772 for (int i = 0; i < items; i++) { 773 int hiIndex = (i + 1) * sizeBits - 1; 774 int loIndex = (i + 0) * sizeBits; 775 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 776 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 777 uint64_t resBits; 778 779 if (size == 4) { 780 floatInt arg1, arg2, res; 781 arg1.i = arg1Bits; 782 arg2.i = arg2Bits; 783 res.f = arg1.f + arg2.f; 784 resBits = res.i; 785 } else { 786 doubleInt arg1, arg2, res; 787 arg1.i = arg1Bits; 788 arg2.i = arg2Bits; 789 res.d = arg1.d + arg2.d; 790 resBits = res.i; 791 } 792 793 result = insertBits(result, hiIndex, loIndex, resBits); 794 } 795 FpDestReg.uqw = result; 796 ''' 797 798 class Msubf(MediaOp): 799 code = ''' 800 union floatInt 801 { 802 float f; 803 uint32_t i; 804 }; 805 union doubleInt 806 { 807 double d; 808 uint64_t i; 809 }; 810 811 assert(srcSize == destSize); 812 int size = srcSize; 813 int sizeBits = size * 8; 814 assert(srcSize == 4 || srcSize == 8); 815 int items = numItems(size); 816 uint64_t result = FpDestReg.uqw; 817 818 for (int i = 0; i < items; i++) { 819 int hiIndex = (i + 1) * sizeBits - 1; 820 int loIndex = (i + 0) * sizeBits; 821 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 822 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 823 uint64_t resBits; 824 825 if (size == 4) { 826 floatInt arg1, arg2, res; 827 arg1.i = arg1Bits; 828 arg2.i = arg2Bits; 829 res.f = arg1.f - arg2.f; 830 resBits = res.i; 831 } else { 832 doubleInt arg1, arg2, res; 833 arg1.i = arg1Bits; 834 arg2.i = arg2Bits; 835 res.d = arg1.d - arg2.d; 836 resBits = res.i; 837 } 838 839 result = insertBits(result, hiIndex, loIndex, resBits); 840 } 841 FpDestReg.uqw = result; 842 ''' 843 844 class Mmulf(MediaOp): 845 code = ''' 846 union floatInt 847 { 848 float f; 849 uint32_t i; 850 }; 851 union doubleInt 852 { 853 double d; 854 uint64_t i; 855 }; 856 857 assert(srcSize == destSize); 858 int size = srcSize; 859 int sizeBits = size * 8; 860 assert(srcSize == 4 || srcSize == 8); 861 int items = numItems(size); 862 uint64_t result = FpDestReg.uqw; 863 864 for (int i = 0; i < items; i++) { 865 int hiIndex = (i + 1) * sizeBits - 1; 866 int loIndex = (i + 0) * sizeBits; 867 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 868 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 869 uint64_t resBits; 870 871 if (size == 4) { 872 floatInt arg1, arg2, res; 873 arg1.i = arg1Bits; 874 arg2.i = arg2Bits; 875 res.f = arg1.f * arg2.f; 876 resBits = res.i; 877 } else { 878 doubleInt arg1, arg2, res; 879 arg1.i = arg1Bits; 880 arg2.i = arg2Bits; 881 res.d = arg1.d * arg2.d; 882 resBits = res.i; 883 } 884 885 result = insertBits(result, hiIndex, loIndex, resBits); 886 } 887 FpDestReg.uqw = result; 888 ''' 889 890 class Mdivf(MediaOp): 891 code = ''' 892 union floatInt 893 { 894 float f; 895 uint32_t i; 896 }; 897 union doubleInt 898 { 899 double d; 900 uint64_t i; 901 }; 902 903 assert(srcSize == destSize); 904 int size = srcSize; 905 int sizeBits = size * 8; 906 assert(srcSize == 4 || srcSize == 8); 907 int items = numItems(size); 908 uint64_t result = FpDestReg.uqw; 909 910 for (int i = 0; i < items; i++) { 911 int hiIndex = (i + 1) * sizeBits - 1; 912 int loIndex = (i + 0) * sizeBits; 913 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 914 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 915 uint64_t resBits; 916 917 if (size == 4) { 918 floatInt arg1, arg2, res; 919 arg1.i = arg1Bits; 920 arg2.i = arg2Bits; 921 res.f = arg1.f / arg2.f; 922 resBits = res.i; 923 } else { 924 doubleInt arg1, arg2, res; 925 arg1.i = arg1Bits; 926 arg2.i = arg2Bits; 927 res.d = arg1.d / arg2.d; 928 resBits = res.i; 929 } 930 931 result = insertBits(result, hiIndex, loIndex, resBits); 932 } 933 FpDestReg.uqw = result; 934 ''' 935 936 class Maddi(MediaOp): 937 code = ''' 938 assert(srcSize == destSize); 939 int size = srcSize; 940 int sizeBits = size * 8; 941 int items = numItems(size); 942 uint64_t result = FpDestReg.uqw; 943 944 for (int i = 0; i < items; i++) { 945 int hiIndex = (i + 1) * sizeBits - 1; 946 int loIndex = (i + 0) * sizeBits; 947 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 948 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 949 uint64_t resBits = arg1Bits + arg2Bits; 950 951 if (ext & 0x2) { 952 if (findCarry(sizeBits, resBits, arg1Bits, arg2Bits)) 953 resBits = mask(sizeBits); 954 } else if (ext & 0x4) { 955 int arg1Sign = bits(arg1Bits, sizeBits - 1); 956 int arg2Sign = bits(arg2Bits, sizeBits - 1); 957 int resSign = bits(resBits, sizeBits - 1); 958 if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { 959 if (resSign == 0) 960 resBits = (ULL(1) << (sizeBits - 1)); 961 else 962 resBits = mask(sizeBits - 1); 963 } 964 } 965 966 result = insertBits(result, hiIndex, loIndex, resBits); 967 } 968 FpDestReg.uqw = result; 969 ''' 970 971 class Msubi(MediaOp): 972 code = ''' 973 assert(srcSize == destSize); 974 int size = srcSize; 975 int sizeBits = size * 8; 976 int items = numItems(size); 977 uint64_t result = FpDestReg.uqw; 978 979 for (int i = 0; i < items; i++) { 980 int hiIndex = (i + 1) * sizeBits - 1; 981 int loIndex = (i + 0) * sizeBits; 982 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 983 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 984 uint64_t resBits = arg1Bits - arg2Bits; 985 986 if (ext & 0x2) { 987 if (arg2Bits > arg1Bits) { 988 resBits = 0; 989 } else if (!findCarry(sizeBits, resBits, 990 arg1Bits, ~arg2Bits)) { 991 resBits = mask(sizeBits); 992 } 993 } else if (ext & 0x4) { 994 int arg1Sign = bits(arg1Bits, sizeBits - 1); 995 int arg2Sign = !bits(arg2Bits, sizeBits - 1); 996 int resSign = bits(resBits, sizeBits - 1); 997 if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { 998 if (resSign == 0) 999 resBits = (ULL(1) << (sizeBits - 1)); 1000 else 1001 resBits = mask(sizeBits - 1); 1002 } 1003 } 1004 1005 result = insertBits(result, hiIndex, loIndex, resBits); 1006 } 1007 FpDestReg.uqw = result; 1008 ''' 1009 1010 class Mmuli(MediaOp): 1011 code = ''' 1012 int srcBits = srcSize * 8; 1013 int destBits = destSize * 8; 1014 assert(destBits <= 64); 1015 assert(destSize >= srcSize); 1016 int items = numItems(destSize); 1017 uint64_t result = FpDestReg.uqw; 1018 1019 for (int i = 0; i < items; i++) { 1020 int offset = 0; 1021 if (ext & 16) { 1022 if (ext & 32) 1023 offset = i * (destBits - srcBits); 1024 else 1025 offset = i * (destBits - srcBits) + srcBits; 1026 } 1027 int srcHiIndex = (i + 1) * srcBits - 1 + offset; 1028 int srcLoIndex = (i + 0) * srcBits + offset; 1029 uint64_t arg1Bits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex); 1030 uint64_t arg2Bits = bits(FpSrcReg2.uqw, srcHiIndex, srcLoIndex); 1031 uint64_t resBits; 1032 1033 if (ext & 0x2) { 1034 int64_t arg1 = arg1Bits | 1035 (0 - (arg1Bits & (ULL(1) << (srcBits - 1)))); 1036 int64_t arg2 = arg2Bits | 1037 (0 - (arg2Bits & (ULL(1) << (srcBits - 1)))); 1038 resBits = (uint64_t)(arg1 * arg2); 1039 } else { 1040 resBits = arg1Bits * arg2Bits; 1041 } 1042 1043 if (ext & 0x4) 1044 resBits += (ULL(1) << (destBits - 1)); 1045 1046 if (ext & 0x8) 1047 resBits >>= destBits; 1048 1049 int destHiIndex = (i + 1) * destBits - 1; 1050 int destLoIndex = (i + 0) * destBits; 1051 result = insertBits(result, destHiIndex, destLoIndex, resBits); 1052 } 1053 FpDestReg.uqw = result; 1054 ''' 1055 1056 class Mavg(MediaOp): 1057 code = ''' 1058 assert(srcSize == destSize); 1059 int size = srcSize; 1060 int sizeBits = size * 8; 1061 int items = numItems(size); 1062 uint64_t result = FpDestReg.uqw; 1063 1064 for (int i = 0; i < items; i++) { 1065 int hiIndex = (i + 1) * sizeBits - 1; 1066 int loIndex = (i + 0) * sizeBits; 1067 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 1068 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 1069 uint64_t resBits = (arg1Bits + arg2Bits + 1) / 2; 1070 1071 result = insertBits(result, hiIndex, loIndex, resBits); 1072 } 1073 FpDestReg.uqw = result; 1074 ''' 1075 1076 class Msad(MediaOp): 1077 code = ''' 1078 int srcBits = srcSize * 8; 1079 int items = sizeof(FloatRegBits) / srcSize; 1080 1081 uint64_t sum = 0; 1082 for (int i = 0; i < items; i++) { 1083 int hiIndex = (i + 1) * srcBits - 1; 1084 int loIndex = (i + 0) * srcBits; 1085 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 1086 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 1087 int64_t resBits = arg1Bits - arg2Bits; 1088 if (resBits < 0) 1089 resBits = -resBits; 1090 sum += resBits; 1091 } 1092 FpDestReg.uqw = sum & mask(destSize * 8); 1093 ''' 1094 1095 class Msrl(MediaOp): 1096 code = ''' 1097 1098 assert(srcSize == destSize); 1099 int size = srcSize; 1100 int sizeBits = size * 8; 1101 int items = numItems(size); 1102 uint64_t shiftAmt = op2.uqw; 1103 uint64_t result = FpDestReg.uqw; 1104 1105 for (int i = 0; i < items; i++) { 1106 int hiIndex = (i + 1) * sizeBits - 1; 1107 int loIndex = (i + 0) * sizeBits; 1108 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 1109 uint64_t resBits; 1110 if (shiftAmt >= sizeBits) { 1111 resBits = 0; 1112 } else { 1113 resBits = (arg1Bits >> shiftAmt) & 1114 mask(sizeBits - shiftAmt); 1115 } 1116 1117 result = insertBits(result, hiIndex, loIndex, resBits); 1118 } 1119 FpDestReg.uqw = result; 1120 ''' 1121 1122 class Msra(MediaOp): 1123 code = ''' 1124 1125 assert(srcSize == destSize); 1126 int size = srcSize; 1127 int sizeBits = size * 8; 1128 int items = numItems(size); 1129 uint64_t shiftAmt = op2.uqw; 1130 uint64_t result = FpDestReg.uqw; 1131 1132 for (int i = 0; i < items; i++) { 1133 int hiIndex = (i + 1) * sizeBits - 1; 1134 int loIndex = (i + 0) * sizeBits; 1135 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 1136 uint64_t resBits; 1137 if (shiftAmt >= sizeBits) { 1138 if (bits(arg1Bits, sizeBits - 1)) 1139 resBits = mask(sizeBits); 1140 else 1141 resBits = 0; 1142 } else { 1143 resBits = (arg1Bits >> shiftAmt); 1144 resBits = resBits | 1145 (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt)))); 1146 } 1147 1148 result = insertBits(result, hiIndex, loIndex, resBits); 1149 } 1150 FpDestReg.uqw = result; 1151 ''' 1152 1153 class Msll(MediaOp): 1154 code = ''' 1155 1156 assert(srcSize == destSize); 1157 int size = srcSize; 1158 int sizeBits = size * 8; 1159 int items = numItems(size); 1160 uint64_t shiftAmt = op2.uqw; 1161 uint64_t result = FpDestReg.uqw; 1162 1163 for (int i = 0; i < items; i++) { 1164 int hiIndex = (i + 1) * sizeBits - 1; 1165 int loIndex = (i + 0) * sizeBits; 1166 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 1167 uint64_t resBits; 1168 if (shiftAmt >= sizeBits) { 1169 resBits = 0; 1170 } else { 1171 resBits = (arg1Bits << shiftAmt); 1172 } 1173 1174 result = insertBits(result, hiIndex, loIndex, resBits); 1175 } 1176 FpDestReg.uqw = result; 1177 ''' 1178 1179 class Cvtf2i(MediaOp): 1180 def __init__(self, dest, src, \ 1181 size = None, destSize = None, srcSize = None, ext = None): 1182 super(Cvtf2i, self).__init__(dest, src,\ 1183 "InstRegIndex(0)", size, destSize, srcSize, ext) 1184 code = ''' 1185 union floatInt 1186 { 1187 float f; 1188 uint32_t i; 1189 }; 1190 union doubleInt 1191 { 1192 double d; 1193 uint64_t i; 1194 }; 1195 1196 assert(destSize == 4 || destSize == 8); 1197 assert(srcSize == 4 || srcSize == 8); 1198 int srcSizeBits = srcSize * 8; 1199 int destSizeBits = destSize * 8; 1200 int items; 1201 int srcStart = 0; 1202 int destStart = 0; 1203 if (srcSize == 2 * destSize) { 1204 items = numItems(srcSize); 1205 if (ext & 0x2) 1206 destStart = destSizeBits * items; 1207 } else if (destSize == 2 * srcSize) { 1208 items = numItems(destSize); 1209 if (ext & 0x2) 1210 srcStart = srcSizeBits * items; 1211 } else { 1212 items = numItems(destSize); 1213 } 1214 uint64_t result = FpDestReg.uqw; 1215 1216 for (int i = 0; i < items; i++) { 1217 int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; 1218 int srcLoIndex = srcStart + (i + 0) * srcSizeBits; 1219 uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex); 1220 double arg; 1221 1222 if (srcSize == 4) { 1223 floatInt fi; 1224 fi.i = argBits; 1225 arg = fi.f; 1226 } else { 1227 doubleInt di; 1228 di.i = argBits; 1229 arg = di.d; 1230 } 1231 1232 if (ext & 0x4) { 1233 if (arg >= 0) 1234 arg += 0.5; 1235 else 1236 arg -= 0.5; 1237 } 1238 1239 if (destSize == 4) { 1240 argBits = (uint32_t)arg; 1241 } else { 1242 argBits = (uint64_t)arg; 1243 } 1244 int destHiIndex = destStart + (i + 1) * destSizeBits - 1; 1245 int destLoIndex = destStart + (i + 0) * destSizeBits; 1246 result = insertBits(result, destHiIndex, destLoIndex, argBits); 1247 } 1248 FpDestReg.uqw = result; 1249 ''' 1250 1251 class Cvti2f(MediaOp): 1252 def __init__(self, dest, src, \ 1253 size = None, destSize = None, srcSize = None, ext = None): 1254 super(Cvti2f, self).__init__(dest, src,\ 1255 "InstRegIndex(0)", size, destSize, srcSize, ext) 1256 code = ''' 1257 union floatInt 1258 { 1259 float f; 1260 uint32_t i; 1261 }; 1262 union doubleInt 1263 { 1264 double d; 1265 uint64_t i; 1266 }; 1267 1268 assert(destSize == 4 || destSize == 8); 1269 assert(srcSize == 4 || srcSize == 8); 1270 int srcSizeBits = srcSize * 8; 1271 int destSizeBits = destSize * 8; 1272 int items; 1273 int srcStart = 0; 1274 int destStart = 0; 1275 if (srcSize == 2 * destSize) { 1276 items = numItems(srcSize); 1277 if (ext & 0x2) 1278 destStart = destSizeBits * items; 1279 } else if (destSize == 2 * srcSize) { 1280 items = numItems(destSize); 1281 if (ext & 0x2) 1282 srcStart = srcSizeBits * items; 1283 } else { 1284 items = numItems(destSize); 1285 } 1286 uint64_t result = FpDestReg.uqw; 1287 1288 for (int i = 0; i < items; i++) { 1289 int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; 1290 int srcLoIndex = srcStart + (i + 0) * srcSizeBits; 1291 uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex); 1292 1293 int64_t sArg = argBits | (0 - (argBits & (ULL(1) << srcHiIndex))); 1294 double arg = sArg; 1295 1296 if (destSize == 4) { 1297 floatInt fi; 1298 fi.f = arg; 1299 argBits = fi.i; 1300 } else { 1301 doubleInt di; 1302 di.d = arg; 1303 argBits = di.i; 1304 } 1305 int destHiIndex = destStart + (i + 1) * destSizeBits - 1; 1306 int destLoIndex = destStart + (i + 0) * destSizeBits; 1307 result = insertBits(result, destHiIndex, destLoIndex, argBits); 1308 } 1309 FpDestReg.uqw = result; 1310 ''' 1311 1312 class Cvtf2f(MediaOp): 1313 def __init__(self, dest, src, \ 1314 size = None, destSize = None, srcSize = None, ext = None): 1315 super(Cvtf2f, self).__init__(dest, src,\ 1316 "InstRegIndex(0)", size, destSize, srcSize, ext) 1317 code = ''' 1318 union floatInt 1319 { 1320 float f; 1321 uint32_t i; 1322 }; 1323 union doubleInt 1324 { 1325 double d; 1326 uint64_t i; 1327 }; 1328 1329 assert(destSize == 4 || destSize == 8); 1330 assert(srcSize == 4 || srcSize == 8); 1331 int srcSizeBits = srcSize * 8; 1332 int destSizeBits = destSize * 8; 1333 int items; 1334 int srcStart = 0; 1335 int destStart = 0; 1336 if (srcSize == 2 * destSize) { 1337 items = numItems(srcSize); 1338 if (ext & 0x2) 1339 destStart = destSizeBits * items; 1340 } else if (destSize == 2 * srcSize) { 1341 items = numItems(destSize); 1342 if (ext & 0x2) 1343 srcStart = srcSizeBits * items; 1344 } else { 1345 items = numItems(destSize); 1346 } 1347 uint64_t result = FpDestReg.uqw; 1348 1349 for (int i = 0; i < items; i++) { 1350 int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; 1351 int srcLoIndex = srcStart + (i + 0) * srcSizeBits; 1352 uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex); 1353 double arg; 1354 1355 if (srcSize == 4) { 1356 floatInt fi; 1357 fi.i = argBits; 1358 arg = fi.f; 1359 } else { 1360 doubleInt di; 1361 di.i = argBits; 1362 arg = di.d; 1363 } 1364 if (destSize == 4) { 1365 floatInt fi; 1366 fi.f = arg; 1367 argBits = fi.i; 1368 } else { 1369 doubleInt di; 1370 di.d = arg; 1371 argBits = di.i; 1372 } 1373 int destHiIndex = destStart + (i + 1) * destSizeBits - 1; 1374 int destLoIndex = destStart + (i + 0) * destSizeBits; 1375 result = insertBits(result, destHiIndex, destLoIndex, argBits); 1376 } 1377 FpDestReg.uqw = result; 1378 ''' 1379 1380 class Mcmpi2r(MediaOp): 1381 code = ''' 1382 union floatInt 1383 { 1384 float f; 1385 uint32_t i; 1386 }; 1387 union doubleInt 1388 { 1389 double d; 1390 uint64_t i; 1391 }; 1392 1393 assert(srcSize == destSize); 1394 int size = srcSize; 1395 int sizeBits = size * 8; 1396 int items = numItems(size); 1397 uint64_t result = FpDestReg.uqw; 1398 1399 for (int i = 0; i < items; i++) { 1400 int hiIndex = (i + 1) * sizeBits - 1; 1401 int loIndex = (i + 0) * sizeBits; 1402 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 1403 int64_t arg1 = arg1Bits | 1404 (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); 1405 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 1406 int64_t arg2 = arg2Bits | 1407 (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); 1408 1409 uint64_t resBits = 0; 1410 if (((ext & 0x2) == 0 && arg1 == arg2) || 1411 ((ext & 0x2) == 0x2 && arg1 > arg2)) 1412 resBits = mask(sizeBits); 1413 1414 result = insertBits(result, hiIndex, loIndex, resBits); 1415 } 1416 FpDestReg.uqw = result; 1417 ''' 1418 1419 class Mcmpf2r(MediaOp): 1420 code = ''' 1421 union floatInt 1422 { 1423 float f; 1424 uint32_t i; 1425 }; 1426 union doubleInt 1427 { 1428 double d; 1429 uint64_t i; 1430 }; 1431 1432 assert(srcSize == destSize); 1433 int size = srcSize; 1434 int sizeBits = size * 8; 1435 int items = numItems(size); 1436 uint64_t result = FpDestReg.uqw; 1437 1438 for (int i = 0; i < items; i++) { 1439 int hiIndex = (i + 1) * sizeBits - 1; 1440 int loIndex = (i + 0) * sizeBits; 1441 uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); 1442 uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); 1443 double arg1, arg2; 1444 1445 if (size == 4) { 1446 floatInt fi; 1447 fi.i = arg1Bits; 1448 arg1 = fi.f; 1449 fi.i = arg2Bits; 1450 arg2 = fi.f; 1451 } else { 1452 doubleInt di; 1453 di.i = arg1Bits; 1454 arg1 = di.d; 1455 di.i = arg2Bits; 1456 arg2 = di.d; 1457 } 1458 1459 uint64_t resBits = 0; 1460 bool nanop = isnan(arg1) || isnan(arg2); 1461 switch (ext & mask(3)) { 1462 case 0: 1463 if (arg1 == arg2 && !nanop) 1464 resBits = mask(sizeBits); 1465 break; 1466 case 1: 1467 if (arg1 < arg2 && !nanop) 1468 resBits = mask(sizeBits); 1469 break; 1470 case 2: 1471 if (arg1 <= arg2 && !nanop) 1472 resBits = mask(sizeBits); 1473 break; 1474 case 3: 1475 if (nanop) 1476 resBits = mask(sizeBits); 1477 break; 1478 case 4: 1479 if (arg1 != arg2 || nanop) 1480 resBits = mask(sizeBits); 1481 break; 1482 case 5: 1483 if (!(arg1 < arg2) || nanop) 1484 resBits = mask(sizeBits); 1485 break; 1486 case 6: 1487 if (!(arg1 <= arg2) || nanop) 1488 resBits = mask(sizeBits); 1489 break; 1490 case 7: 1491 if (!nanop) 1492 resBits = mask(sizeBits); 1493 break; 1494 }; 1495 1496 result = insertBits(result, hiIndex, loIndex, resBits); 1497 } 1498 FpDestReg.uqw = result; 1499 ''' 1500 1501 class Mcmpf2rf(MediaOp): 1502 def __init__(self, src1, src2,\ 1503 size = None, destSize = None, srcSize = None, ext = None): 1504 super(Mcmpf2rf, self).__init__("InstRegIndex(0)", src1,\ 1505 src2, size, destSize, srcSize, ext) 1506 code = ''' 1507 union floatInt 1508 { 1509 float f; 1510 uint32_t i; 1511 }; 1512 union doubleInt 1513 { 1514 double d; 1515 uint64_t i; 1516 }; 1517 1518 assert(srcSize == destSize); 1519 assert(srcSize == 4 || srcSize == 8); 1520 int size = srcSize; 1521 int sizeBits = size * 8; 1522 1523 double arg1, arg2; 1524 uint64_t arg1Bits = bits(FpSrcReg1.uqw, sizeBits - 1, 0); 1525 uint64_t arg2Bits = bits(FpSrcReg2.uqw, sizeBits - 1, 0); 1526 if (size == 4) { 1527 floatInt fi; 1528 fi.i = arg1Bits; 1529 arg1 = fi.f; 1530 fi.i = arg2Bits; 1531 arg2 = fi.f; 1532 } else { 1533 doubleInt di; 1534 di.i = arg1Bits; 1535 arg1 = di.d; 1536 di.i = arg2Bits; 1537 arg2 = di.d; 1538 } 1539 1540 // ZF PF CF 1541 // Unordered 1 1 1 1542 // Greater than 0 0 0 1543 // Less than 0 0 1 1544 // Equal 1 0 0 1545 // OF = SF = AF = 0 1546 ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit | 1547 ZFBit | PFBit | CFBit); 1548 if (isnan(arg1) || isnan(arg2)) 1549 ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit); 1550 else if(arg1 < arg2) 1551 ccFlagBits = ccFlagBits | CFBit; 1552 else if(arg1 == arg2) 1553 ccFlagBits = ccFlagBits | ZFBit; 1554 ''' 1555}}; 1556