1// -*- mode:c++ -*- 2 3// Copyright (c) 2012-2013, 2016-2018 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Thomas Grocutt 39// Edmund Grimley Evans 40 41let {{ 42 43 header_output = "" 44 decoder_output = "" 45 exec_output = "" 46 47 zeroSveVecRegUpperPartCode = ''' 48 ArmISA::ISA::zeroSveVecRegUpperPart(%s, 49 ArmStaticInst::getCurSveVecLen<uint64_t>(xc->tcBase())); 50 ''' 51 52 fmovImmSCode = vfp64EnabledCheckCode + ''' 53 AA64FpDestP0_uw = bits(imm, 31, 0); 54 AA64FpDestP1_uw = 0; 55 AA64FpDestP2_uw = 0; 56 AA64FpDestP3_uw = 0; 57 ''' 58 fmovImmSIop = InstObjParams("fmov", "FmovImmS", "FpRegImmOp", 59 { "code": fmovImmSCode, 60 "op_class": "FloatMiscOp" }, []) 61 fmovImmSIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 62 header_output += FpRegImmOpDeclare.subst(fmovImmSIop); 63 decoder_output += FpRegImmOpConstructor.subst(fmovImmSIop); 64 exec_output += BasicExecute.subst(fmovImmSIop); 65 66 fmovImmDCode = vfp64EnabledCheckCode + ''' 67 AA64FpDestP0_uw = bits(imm, 31, 0); 68 AA64FpDestP1_uw = bits(imm, 63, 32); 69 AA64FpDestP2_uw = 0; 70 AA64FpDestP3_uw = 0; 71 ''' 72 fmovImmDIop = InstObjParams("fmov", "FmovImmD", "FpRegImmOp", 73 { "code": fmovImmDCode, 74 "op_class": "FloatMiscOp" }, []) 75 fmovImmDIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 76 header_output += FpRegImmOpDeclare.subst(fmovImmDIop); 77 decoder_output += AA64FpRegImmOpConstructor.subst(fmovImmDIop); 78 exec_output += BasicExecute.subst(fmovImmDIop); 79 80 fmovRegSCode = vfp64EnabledCheckCode + ''' 81 AA64FpDestP0_uw = AA64FpOp1P0_uw; 82 AA64FpDestP1_uw = 0; 83 AA64FpDestP2_uw = 0; 84 AA64FpDestP3_uw = 0; 85 ''' 86 fmovRegSIop = InstObjParams("fmov", "FmovRegS", "FpRegRegOp", 87 { "code": fmovRegSCode, 88 "op_class": "FloatMiscOp" }, []) 89 fmovRegSIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 90 header_output += FpRegRegOpDeclare.subst(fmovRegSIop); 91 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegSIop); 92 exec_output += BasicExecute.subst(fmovRegSIop); 93 94 fmovRegDCode = vfp64EnabledCheckCode + ''' 95 AA64FpDestP0_uw = AA64FpOp1P0_uw; 96 AA64FpDestP1_uw = AA64FpOp1P1_uw; 97 AA64FpDestP2_uw = 0; 98 AA64FpDestP3_uw = 0; 99 ''' 100 fmovRegDIop = InstObjParams("fmov", "FmovRegD", "FpRegRegOp", 101 { "code": fmovRegDCode, 102 "op_class": "FloatMiscOp" }, []) 103 fmovRegDIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 104 header_output += FpRegRegOpDeclare.subst(fmovRegDIop); 105 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegDIop); 106 exec_output += BasicExecute.subst(fmovRegDIop); 107 108 fmovCoreRegWCode = vfp64EnabledCheckCode + ''' 109 AA64FpDestP0_uw = WOp1_uw; 110 AA64FpDestP1_uw = 0; 111 AA64FpDestP2_uw = 0; 112 AA64FpDestP3_uw = 0; 113 ''' 114 fmovCoreRegWIop = InstObjParams("fmov", "FmovCoreRegW", "FpRegRegOp", 115 { "code": fmovCoreRegWCode, 116 "op_class": "FloatMiscOp" }, []) 117 fmovCoreRegWIop.snippets["code"] += zeroSveVecRegUpperPartCode % \ 118 "AA64FpDest" 119 header_output += FpRegRegOpDeclare.subst(fmovCoreRegWIop); 120 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegWIop); 121 exec_output += BasicExecute.subst(fmovCoreRegWIop); 122 123 fmovCoreRegXCode = vfp64EnabledCheckCode + ''' 124 AA64FpDestP0_uw = XOp1_ud; 125 AA64FpDestP1_uw = XOp1_ud >> 32; 126 AA64FpDestP2_uw = 0; 127 AA64FpDestP3_uw = 0; 128 ''' 129 fmovCoreRegXIop = InstObjParams("fmov", "FmovCoreRegX", "FpRegRegOp", 130 { "code": fmovCoreRegXCode, 131 "op_class": "FloatMiscOp" }, []) 132 fmovCoreRegXIop.snippets["code"] += zeroSveVecRegUpperPartCode % \ 133 "AA64FpDest" 134 header_output += FpRegRegOpDeclare.subst(fmovCoreRegXIop); 135 decoder_output += AA64FpRegRegOpConstructor.subst(fmovCoreRegXIop); 136 exec_output += BasicExecute.subst(fmovCoreRegXIop); 137 138 fmovUCoreRegXCode = vfp64EnabledCheckCode + ''' 139 /* Explicitly merge with previous value */ 140 AA64FpDestP0_uw = AA64FpDestP0_uw; 141 AA64FpDestP1_uw = AA64FpDestP1_uw; 142 AA64FpDestP2_uw = XOp1_ud; 143 AA64FpDestP3_uw = XOp1_ud >> 32;''' 144 fmovUCoreRegXIop = InstObjParams("fmov", "FmovUCoreRegX", "FpRegRegOp", 145 { "code": fmovUCoreRegXCode, 146 "op_class": "FloatMiscOp" }, []) 147 fmovUCoreRegXIop.snippets["code"] += zeroSveVecRegUpperPartCode % \ 148 "AA64FpDest" 149 header_output += FpRegRegOpDeclare.subst(fmovUCoreRegXIop); 150 decoder_output += AA64FpRegRegOpConstructor.subst(fmovUCoreRegXIop); 151 exec_output += BasicExecute.subst(fmovUCoreRegXIop); 152 153 fmovRegCoreWCode = vfp64EnabledCheckCode + ''' 154 WDest = AA64FpOp1P0_uw; 155 ''' 156 fmovRegCoreWIop = InstObjParams("fmov", "FmovRegCoreW", "FpRegRegOp", 157 { "code": fmovRegCoreWCode, 158 "op_class": "FloatMiscOp" }, []) 159 header_output += FpRegRegOpDeclare.subst(fmovRegCoreWIop); 160 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreWIop); 161 exec_output += BasicExecute.subst(fmovRegCoreWIop); 162 163 fmovRegCoreXCode = vfp64EnabledCheckCode + ''' 164 XDest = ( ((uint64_t) AA64FpOp1P1_uw) << 32) | AA64FpOp1P0_uw; 165 ''' 166 fmovRegCoreXIop = InstObjParams("fmov", "FmovRegCoreX", "FpRegRegOp", 167 { "code": fmovRegCoreXCode, 168 "op_class": "FloatMiscOp" }, []) 169 header_output += FpRegRegOpDeclare.subst(fmovRegCoreXIop); 170 decoder_output += AA64FpRegRegOpConstructor.subst(fmovRegCoreXIop); 171 exec_output += BasicExecute.subst(fmovRegCoreXIop); 172 173 fmovURegCoreXCode = vfp64EnabledCheckCode + ''' 174 XDest = ( ((uint64_t) AA64FpOp1P3_uw) << 32) | AA64FpOp1P2_uw; 175 ''' 176 fmovURegCoreXIop = InstObjParams("fmov", "FmovURegCoreX", "FpRegRegOp", 177 { "code": fmovURegCoreXCode, 178 "op_class": "FloatMiscOp" }, []) 179 header_output += FpRegRegOpDeclare.subst(fmovURegCoreXIop); 180 decoder_output += AA64FpRegRegOpConstructor.subst(fmovURegCoreXIop); 181 exec_output += BasicExecute.subst(fmovURegCoreXIop); 182}}; 183 184let {{ 185 186 header_output = "" 187 decoder_output = "" 188 exec_output = "" 189 190 halfIntConvCode = vfp64EnabledCheckCode + ''' 191 FPSCR fpscr = (FPSCR) FpscrExc; 192 uint16_t cOp1 = AA64FpOp1P0_uw; 193 uint16_t cDest = %(op)s; 194 AA64FpDestP0_uw = cDest; 195 AA64FpDestP1_uw = 0; 196 AA64FpDestP2_uw = 0; 197 AA64FpDestP3_uw = 0; 198 FpscrExc = fpscr; 199 ''' 200 201 halfIntConvCode2 = vfp64EnabledCheckCode + ''' 202 FPSCR fpscr = (FPSCR) FpscrExc; 203 uint16_t cOp1 = AA64FpOp1P0_uw; 204 uint16_t cOp2 = AA64FpOp2P0_uw; 205 uint16_t cDest = %(op)s; 206 AA64FpDestP0_uw = cDest; 207 AA64FpDestP1_uw = 0; 208 AA64FpDestP2_uw = 0; 209 AA64FpDestP3_uw = 0; 210 FpscrExc = fpscr; 211 ''' 212 213 halfBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \ 214 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" 215 halfUnaryOp = "unaryOp(fpscr, AA64FpOp1P0," + \ 216 "%(func)s, fpscr.fz, fpscr.rMode)" 217 218 singleIntConvCode = vfp64EnabledCheckCode + ''' 219 FPSCR fpscr = (FPSCR) FpscrExc; 220 uint32_t cOp1 = AA64FpOp1P0_uw; 221 uint32_t cDest = %(op)s; 222 AA64FpDestP0_uw = cDest; 223 AA64FpDestP1_uw = 0; 224 AA64FpDestP2_uw = 0; 225 AA64FpDestP3_uw = 0; 226 FpscrExc = fpscr; 227 ''' 228 229 singleIntConvCode2 = vfp64EnabledCheckCode + ''' 230 FPSCR fpscr = (FPSCR) FpscrExc; 231 uint32_t cOp1 = AA64FpOp1P0_uw; 232 uint32_t cOp2 = AA64FpOp2P0_uw; 233 uint32_t cDest = %(op)s; 234 AA64FpDestP0_uw = cDest; 235 AA64FpDestP1_uw = 0; 236 AA64FpDestP2_uw = 0; 237 AA64FpDestP3_uw = 0; 238 FpscrExc = fpscr; 239 ''' 240 241 singleBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \ 242 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" 243 singleUnaryOp = "unaryOp(fpscr, AA64FpOp1P0, %(func)s, fpscr.fz, fpscr.rMode)" 244 245 doubleIntConvCode = vfp64EnabledCheckCode + ''' 246 FPSCR fpscr = (FPSCR) FpscrExc; 247 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw; 248 uint64_t cDest = %(op)s; 249 AA64FpDestP0_uw = cDest & 0xFFFFFFFF; 250 AA64FpDestP1_uw = cDest >> 32; 251 AA64FpDestP2_uw = 0; 252 AA64FpDestP3_uw = 0; 253 FpscrExc = fpscr; 254 ''' 255 256 doubleIntConvCode2 = vfp64EnabledCheckCode + ''' 257 FPSCR fpscr = (FPSCR) FpscrExc; 258 uint64_t cOp1 = ((uint64_t) AA64FpOp1P1_uw) << 32 | AA64FpOp1P0_uw; 259 uint64_t cOp2 = ((uint64_t) AA64FpOp2P1_uw) << 32 | AA64FpOp2P0_uw; 260 uint64_t cDest = %(op)s; 261 AA64FpDestP0_uw = cDest & 0xFFFFFFFF; 262 AA64FpDestP1_uw = cDest >> 32; 263 AA64FpDestP2_uw = 0; 264 AA64FpDestP3_uw = 0; 265 FpscrExc = fpscr; 266 ''' 267 268 doubleBinOp = ''' 269 binaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), 270 dbl(AA64FpOp2P0_uw, AA64FpOp2P1_uw), 271 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode); 272 ''' 273 doubleUnaryOp = ''' 274 unaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), %(func)s, 275 fpscr.fz, fpscr.rMode) 276 ''' 277 278 def buildTernaryFpOp(name, opClass, hOp, sOp, dOp): 279 global header_output, decoder_output, exec_output 280 for suffix in "D", "S", "H": 281 code = vfp64EnabledCheckCode + ''' 282 FPSCR fpscr = (FPSCR) FpscrExc; 283 ''' 284 if suffix == "H": 285 code += ''' 286 uint16_t cOp1 = AA64FpOp1P0_uw; 287 uint16_t cOp2 = AA64FpOp2P0_uw; 288 uint16_t cOp3 = AA64FpOp3P0_uw; 289 uint16_t cDest; 290 ''' "cDest = " + hOp + ";" + ''' 291 AA64FpDestP0_uw = cDest; 292 AA64FpDestP1_uw = 0; 293 ''' 294 elif suffix == "S": 295 code += ''' 296 uint32_t cOp1 = AA64FpOp1P0_uw; 297 uint32_t cOp2 = AA64FpOp2P0_uw; 298 uint32_t cOp3 = AA64FpOp3P0_uw; 299 uint32_t cDest; 300 ''' "cDest = " + sOp + ";" + ''' 301 AA64FpDestP0_uw = cDest; 302 AA64FpDestP1_uw = 0; 303 ''' 304 elif suffix == "D": 305 code += ''' 306 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 307 uint64_t cOp2 = AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32; 308 uint64_t cOp3 = AA64FpOp3P0_uw | (uint64_t)AA64FpOp3P1_uw << 32; 309 uint64_t cDest; 310 ''' "cDest = " + dOp + ";" + ''' 311 AA64FpDestP0_uw = cDest; 312 AA64FpDestP1_uw = cDest >> 32; 313 ''' 314 code += ''' 315 AA64FpDestP2_uw = 0; 316 AA64FpDestP3_uw = 0; 317 FpscrExc = fpscr; 318 ''' 319 320 iop = InstObjParams(name.lower(), name + suffix, 321 "FpRegRegRegRegOp", 322 { "code": code, "op_class": opClass }, []) 323 iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 324 325 header_output += AA64FpRegRegRegRegOpDeclare.subst(iop) 326 decoder_output += AA64FpRegRegRegRegOpConstructor.subst(iop) 327 exec_output += BasicExecute.subst(iop) 328 329 buildTernaryFpOp("FMAdd", "FloatMultAccOp", 330 "fplibMulAdd<uint16_t>(cOp3, cOp1, cOp2, fpscr)", 331 "fplibMulAdd<uint32_t>(cOp3, cOp1, cOp2, fpscr)", 332 "fplibMulAdd<uint64_t>(cOp3, cOp1, cOp2, fpscr)" ) 333 buildTernaryFpOp("FMSub", "FloatMultAccOp", 334 "fplibMulAdd<uint16_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 335 "fplibMulAdd<uint32_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 336 "fplibMulAdd<uint64_t>(cOp3, fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" ) 337 buildTernaryFpOp("FNMAdd", "FloatMultAccOp", 338 "fplibMulAdd<uint16_t>(fplibNeg<uint16_t>(cOp3), " + 339 "fplibNeg<uint16_t>(cOp1), cOp2, fpscr)", 340 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), " + 341 "fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 342 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), " + 343 "fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" ) 344 buildTernaryFpOp("FNMSub", "FloatMultAccOp", 345 "fplibMulAdd<uint16_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)", 346 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)", 347 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), cOp1, cOp2, fpscr)" ) 348 349 def buildBinFpOp(name, Name, base, opClass, halfOp, singleOp, doubleOp): 350 global header_output, decoder_output, exec_output 351 352 code = halfIntConvCode2 % { "op": halfOp } 353 hIop = InstObjParams(name, Name + "H", base, 354 { "code": code, 355 "op_class": opClass }, []) 356 hIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 357 358 code = singleIntConvCode2 % { "op": singleOp } 359 sIop = InstObjParams(name, Name + "S", base, 360 { "code": code, 361 "op_class": opClass }, []) 362 sIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 363 364 code = doubleIntConvCode2 % { "op": doubleOp } 365 dIop = InstObjParams(name, Name + "D", base, 366 { "code": code, 367 "op_class": opClass }, []) 368 dIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 369 370 declareTempl = eval( base + "Declare"); 371 constructorTempl = eval("AA64" + base + "Constructor"); 372 373 for iop in hIop, sIop, dIop: 374 header_output += declareTempl.subst(iop) 375 decoder_output += constructorTempl.subst(iop) 376 exec_output += BasicExecute.subst(iop) 377 378 buildBinFpOp("fadd", "FAdd", "FpRegRegRegOp", "FloatAddOp", 379 "fplibAdd<uint16_t>(cOp1, cOp2, fpscr)", 380 "fplibAdd<uint32_t>(cOp1, cOp2, fpscr)", 381 "fplibAdd<uint64_t>(cOp1, cOp2, fpscr)") 382 buildBinFpOp("fsub", "FSub", "FpRegRegRegOp", "FloatAddOp", 383 "fplibSub<uint16_t>(cOp1, cOp2, fpscr)", 384 "fplibSub<uint32_t>(cOp1, cOp2, fpscr)", 385 "fplibSub<uint64_t>(cOp1, cOp2, fpscr)") 386 buildBinFpOp("fdiv", "FDiv", "FpRegRegRegOp", "FloatDivOp", 387 "fplibDiv<uint16_t>(cOp1, cOp2, fpscr)", 388 "fplibDiv<uint32_t>(cOp1, cOp2, fpscr)", 389 "fplibDiv<uint64_t>(cOp1, cOp2, fpscr)") 390 buildBinFpOp("fmul", "FMul", "FpRegRegRegOp", "FloatMultOp", 391 "fplibMul<uint16_t>(cOp1, cOp2, fpscr)", 392 "fplibMul<uint32_t>(cOp1, cOp2, fpscr)", 393 "fplibMul<uint64_t>(cOp1, cOp2, fpscr)") 394 buildBinFpOp("fnmul", "FNMul", "FpRegRegRegOp", "FloatMultOp", 395 "fplibNeg<uint16_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))", 396 "fplibNeg<uint32_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))", 397 "fplibNeg<uint64_t>(fplibMul<uint64_t>(cOp1, cOp2, fpscr))") 398 buildBinFpOp("fmin", "FMin", "FpRegRegRegOp", "FloatCmpOp", 399 "fplibMin<uint16_t>(cOp1, cOp2, fpscr)", 400 "fplibMin<uint32_t>(cOp1, cOp2, fpscr)", 401 "fplibMin<uint64_t>(cOp1, cOp2, fpscr)") 402 buildBinFpOp("fmax", "FMax", "FpRegRegRegOp", "FloatCmpOp", 403 "fplibMax<uint16_t>(cOp1, cOp2, fpscr)", 404 "fplibMax<uint32_t>(cOp1, cOp2, fpscr)", 405 "fplibMax<uint64_t>(cOp1, cOp2, fpscr)") 406 buildBinFpOp("fminnm", "FMinNM", "FpRegRegRegOp", "FloatCmpOp", 407 "fplibMinNum<uint16_t>(cOp1, cOp2, fpscr)", 408 "fplibMinNum<uint32_t>(cOp1, cOp2, fpscr)", 409 "fplibMinNum<uint64_t>(cOp1, cOp2, fpscr)") 410 buildBinFpOp("fmaxnm", "FMaxNM", "FpRegRegRegOp", "FloatCmpOp", 411 "fplibMaxNum<uint16_t>(cOp1, cOp2, fpscr)", 412 "fplibMaxNum<uint32_t>(cOp1, cOp2, fpscr)", 413 "fplibMaxNum<uint64_t>(cOp1, cOp2, fpscr)") 414 415 def buildUnaryFpOp(name, Name, base, opClass, 416 halfOp, singleOp, doubleOp = None): 417 if doubleOp is None: 418 doubleOp = singleOp 419 global header_output, decoder_output, exec_output 420 421 code = halfIntConvCode % { "op": halfOp } 422 hIop = InstObjParams(name, Name + "H", base, 423 { "code": code, 424 "op_class": opClass }, []) 425 hIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 426 code = singleIntConvCode % { "op": singleOp } 427 sIop = InstObjParams(name, Name + "S", base, 428 { "code": code, 429 "op_class": opClass }, []) 430 sIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 431 code = doubleIntConvCode % { "op": doubleOp } 432 dIop = InstObjParams(name, Name + "D", base, 433 { "code": code, 434 "op_class": opClass }, []) 435 dIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 436 437 declareTempl = eval( base + "Declare"); 438 constructorTempl = eval("AA64" + base + "Constructor"); 439 440 for iop in hIop, sIop, dIop: 441 header_output += declareTempl.subst(iop) 442 decoder_output += constructorTempl.subst(iop) 443 exec_output += BasicExecute.subst(iop) 444 445 buildUnaryFpOp("fsqrt", "FSqrt", "FpRegRegOp", "FloatSqrtOp", 446 "fplibSqrt<uint16_t>(cOp1, fpscr)", 447 "fplibSqrt<uint32_t>(cOp1, fpscr)", 448 "fplibSqrt<uint64_t>(cOp1, fpscr)") 449 450 def buildSimpleUnaryFpOp(name, Name, base, opClass, halfOp, singleOp, 451 doubleOp = None, isIntConv = True): 452 if doubleOp is None: 453 doubleOp = singleOp 454 global header_output, decoder_output, exec_output 455 456 if isIntConv: 457 hCode = halfIntConvCode 458 sCode = singleIntConvCode 459 dCode = doubleIntConvCode 460 else: 461 hCode = halfCode 462 sCode = singleCode 463 dCode = doubleCode 464 465 for code, op, suffix in [[hCode, halfOp, "H"], 466 [sCode, singleOp, "S"], 467 [dCode, doubleOp, "D"]]: 468 iop = InstObjParams(name, Name + suffix, base, 469 { "code": code % { "op": op }, 470 "op_class": opClass }, []) 471 iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 472 473 declareTempl = eval( base + "Declare"); 474 constructorTempl = eval("AA64" + base + "Constructor"); 475 476 header_output += declareTempl.subst(iop) 477 decoder_output += constructorTempl.subst(iop) 478 exec_output += BasicExecute.subst(iop) 479 480 buildSimpleUnaryFpOp("fneg", "FNeg", "FpRegRegOp", "FloatMiscOp", 481 "fplibNeg<uint16_t>(cOp1)", 482 "fplibNeg<uint32_t>(cOp1)", 483 "fplibNeg<uint64_t>(cOp1)") 484 buildSimpleUnaryFpOp("fabs", "FAbs", "FpRegRegOp", "FloatMiscOp", 485 "fplibAbs<uint16_t>(cOp1)", 486 "fplibAbs<uint32_t>(cOp1)", 487 "fplibAbs<uint64_t>(cOp1)") 488 buildSimpleUnaryFpOp("frintn", "FRIntN", "FpRegRegOp", "FloatMiscOp", 489 "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)", 490 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)", 491 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)") 492 buildSimpleUnaryFpOp("frintp", "FRIntP", "FpRegRegOp", "FloatMiscOp", 493 "fplibRoundInt<uint16_t>(cOp1, FPRounding_POSINF, false, fpscr)", 494 "fplibRoundInt<uint32_t>(cOp1, FPRounding_POSINF, false, fpscr)", 495 "fplibRoundInt<uint64_t>(cOp1, FPRounding_POSINF, false, fpscr)") 496 buildSimpleUnaryFpOp("frintm", "FRIntM", "FpRegRegOp", "FloatMiscOp", 497 "fplibRoundInt<uint16_t>(cOp1, FPRounding_NEGINF, false, fpscr)", 498 "fplibRoundInt<uint32_t>(cOp1, FPRounding_NEGINF, false, fpscr)", 499 "fplibRoundInt<uint64_t>(cOp1, FPRounding_NEGINF, false, fpscr)") 500 buildSimpleUnaryFpOp("frintz", "FRIntZ", "FpRegRegOp", "FloatMiscOp", 501 "fplibRoundInt<uint16_t>(cOp1, FPRounding_ZERO, false, fpscr)", 502 "fplibRoundInt<uint32_t>(cOp1, FPRounding_ZERO, false, fpscr)", 503 "fplibRoundInt<uint64_t>(cOp1, FPRounding_ZERO, false, fpscr)") 504 buildSimpleUnaryFpOp("frinta", "FRIntA", "FpRegRegOp", "FloatMiscOp", 505 "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)", 506 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)", 507 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)") 508 buildSimpleUnaryFpOp("frinti", "FRIntI", "FpRegRegOp", "FloatMiscOp", 509 "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), false, fpscr)", 510 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), false, fpscr)", 511 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), false, fpscr)") 512 buildSimpleUnaryFpOp("frintx", "FRIntX", "FpRegRegOp", "FloatMiscOp", 513 "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), true, fpscr)", 514 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), true, fpscr)", 515 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), true, fpscr)") 516}}; 517 518let {{ 519 520 header_output = "" 521 decoder_output = "" 522 exec_output = "" 523 524 # Creates the integer to floating point instructions, including variants for 525 # signed/unsigned, float/double, etc 526 for regL, regOpL, width in [["W", "w", 32], 527 ["X", "d", 64]]: 528 for isDouble in True, False: 529 for us, usCode in [["U", "uint%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)], 530 ["S", "int%d_t cSrc = %sOp1_u%s;" %(width, regL, regOpL)]]: 531 fcvtIntFpDCode = vfp64EnabledCheckCode + ''' 532 FPSCR fpscr = (FPSCR) FpscrExc; 533 %s 534 ''' %(usCode) 535 536 if isDouble: 537 fcvtIntFpDCode += ''' 538 uint64_t cDest = fplibFixedToFP<uint64_t>(cSrc, 0, 539 %s, FPCRRounding(fpscr), fpscr); 540 AA64FpDestP0_uw = cDest; 541 AA64FpDestP1_uw = cDest >> 32; 542 ''' % ("true" if us == "U" else "false") 543 else: 544 fcvtIntFpDCode += ''' 545 uint32_t cDest = fplibFixedToFP<uint32_t>(cSrc, 0, 546 %s, FPCRRounding(fpscr), fpscr); 547 AA64FpDestP0_uw = cDest; 548 AA64FpDestP1_uw = 0; 549 ''' % ("true" if us == "U" else "false") 550 fcvtIntFpDCode += ''' 551 AA64FpDestP2_uw = 0; 552 AA64FpDestP3_uw = 0; 553 FpscrExc = fpscr; 554 ''' 555 556 instName = "Fcvt%s%sIntFp%s" %(regL, us, "D" if isDouble else "S") 557 mnem = "%scvtf" %(us.lower()) 558 fcvtIntFpDIop = InstObjParams(mnem, instName, "FpRegRegOp", 559 { "code": fcvtIntFpDCode, 560 "op_class": "FloatCvtOp" }, []) 561 fcvtIntFpDIop.snippets["code"] += \ 562 zeroSveVecRegUpperPartCode % "AA64FpDest" 563 564 header_output += FpRegRegOpDeclare.subst(fcvtIntFpDIop); 565 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtIntFpDIop); 566 exec_output += BasicExecute.subst(fcvtIntFpDIop); 567 568 # Generates the floating point to integer conversion instructions in various 569 # variants, eg signed/unsigned 570 def buildFpCvtIntOp(isDouble, isSigned, isXReg): 571 global header_output, decoder_output, exec_output 572 573 for rmode, roundingMode in [["N", "FPRounding_TIEEVEN"], 574 ["P", "FPRounding_POSINF"], 575 ["M", "FPRounding_NEGINF"], 576 ["Z", "FPRounding_ZERO"], 577 ["A", "FPRounding_TIEAWAY"]]: 578 fcvtFpIntCode = vfp64EnabledCheckCode + ''' 579 FPSCR fpscr = (FPSCR) FpscrExc;''' 580 if isDouble: 581 fcvtFpIntCode += ''' 582 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 583 ''' 584 else: 585 fcvtFpIntCode += "uint32_t cOp1 = AA64FpOp1P0_uw;" 586 587 fcvtFpIntCode += ''' 588 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 0, %s, %s, fpscr); 589 FpscrExc = fpscr; 590 ''' %("X" if isXReg else "W", 591 "64" if isDouble else "32", 592 "64" if isXReg else "32", 593 "false" if isSigned else "true", 594 roundingMode) 595 596 instName = "FcvtFp%sInt%s%s%s" %("S" if isSigned else "U", 597 "X" if isXReg else "W", 598 "D" if isDouble else "S", rmode) 599 mnem = "fcvt%s%s" %(rmode, "s" if isSigned else "u") 600 fcvtFpIntIop = InstObjParams(mnem, instName, "FpRegRegOp", 601 { "code": fcvtFpIntCode, 602 "op_class": "FloatCvtOp" }, []) 603 header_output += FpRegRegOpDeclare.subst(fcvtFpIntIop); 604 decoder_output += FpRegRegOpConstructor.subst(fcvtFpIntIop); 605 exec_output += BasicExecute.subst(fcvtFpIntIop); 606 607 # Now actually do the building with the different variants 608 for isDouble in True, False: 609 for isSigned in True, False: 610 for isXReg in True, False: 611 buildFpCvtIntOp(isDouble, isSigned, isXReg) 612 613 fcvtFpSFpDCode = vfp64EnabledCheckCode + ''' 614 FPSCR fpscr = (FPSCR) FpscrExc; 615 uint64_t cDest = fplibConvert<uint32_t, uint64_t>(AA64FpOp1P0_uw, 616 FPCRRounding(fpscr), fpscr); 617 AA64FpDestP0_uw = cDest; 618 AA64FpDestP1_uw = cDest >> 32; 619 AA64FpDestP2_uw = 0; 620 AA64FpDestP3_uw = 0; 621 FpscrExc = fpscr; 622 ''' 623 fcvtFpSFpDIop = InstObjParams("fcvt", "FCvtFpSFpD", "FpRegRegOp", 624 { "code": fcvtFpSFpDCode, 625 "op_class": "FloatCvtOp" }, []) 626 fcvtFpSFpDIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 627 header_output += FpRegRegOpDeclare.subst(fcvtFpSFpDIop); 628 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpSFpDIop); 629 exec_output += BasicExecute.subst(fcvtFpSFpDIop); 630 631 fcvtFpDFpSCode = vfp64EnabledCheckCode + ''' 632 FPSCR fpscr = (FPSCR) FpscrExc; 633 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 634 AA64FpDestP0_uw = fplibConvert<uint64_t, uint32_t>(cOp1, 635 FPCRRounding(fpscr), fpscr); 636 AA64FpDestP1_uw = 0; 637 AA64FpDestP2_uw = 0; 638 AA64FpDestP3_uw = 0; 639 FpscrExc = fpscr; 640 ''' 641 fcvtFpDFpSIop = InstObjParams("fcvt", "FcvtFpDFpS", "FpRegRegOp", 642 {"code": fcvtFpDFpSCode, 643 "op_class": "FloatCvtOp" }, []) 644 fcvtFpDFpSIop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 645 header_output += FpRegRegOpDeclare.subst(fcvtFpDFpSIop); 646 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpDFpSIop); 647 exec_output += BasicExecute.subst(fcvtFpDFpSIop); 648 649 # Half precision to single or double precision conversion 650 for isDouble in True, False: 651 code = vfp64EnabledCheckCode + ''' 652 FPSCR fpscr = (FPSCR) FpscrExc; 653 %s cDest = fplibConvert<uint16_t, uint%s_t>(AA64FpOp1P0_uw, 654 FPCRRounding(fpscr), fpscr); 655 ''' % ("uint64_t" if isDouble else "uint32_t", 656 "64" if isDouble else "32") 657 if isDouble: 658 code += ''' 659 AA64FpDestP0_uw = cDest; 660 AA64FpDestP1_uw = cDest >> 32; 661 ''' 662 else: 663 code += ''' 664 AA64FpDestP0_uw = cDest; 665 AA64FpDestP1_uw = 0; 666 ''' 667 code += ''' 668 AA64FpDestP2_uw = 0; 669 AA64FpDestP3_uw = 0; 670 FpscrExc = fpscr; 671 ''' 672 673 instName = "FcvtFpHFp%s" %("D" if isDouble else "S") 674 fcvtFpHFpIop = InstObjParams("fcvt", instName, "FpRegRegOp", 675 { "code": code, 676 "op_class": "FloatCvtOp" }, []) 677 fcvtFpHFpIop.snippets["code"] += zeroSveVecRegUpperPartCode % \ 678 "AA64FpDest" 679 header_output += FpRegRegOpDeclare.subst(fcvtFpHFpIop); 680 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpHFpIop); 681 exec_output += BasicExecute.subst(fcvtFpHFpIop); 682 683 # single or double precision to Half precision conversion 684 for isDouble in True, False: 685 code = vfp64EnabledCheckCode + ''' 686 FPSCR fpscr = (FPSCR) FpscrExc; 687 %s; 688 AA64FpDestP0_uw = fplibConvert<uint%s_t, uint16_t>(cOp1, 689 FPCRRounding(fpscr), fpscr); 690 AA64FpDestP1_uw = 0; 691 AA64FpDestP2_uw = 0; 692 AA64FpDestP3_uw = 0; 693 FpscrExc = fpscr; 694 ''' % ("uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 695 if isDouble else "uint32_t cOp1 = AA64FpOp1P0_uw", 696 "64" if isDouble else "32") 697 698 instName = "FcvtFp%sFpH" %("D" if isDouble else "S") 699 fcvtFpFpHIop = InstObjParams("fcvt", instName, "FpRegRegOp", 700 { "code": code, 701 "op_class": "FloatCvtOp" }, []) 702 fcvtFpFpHIop.snippets["code"] += zeroSveVecRegUpperPartCode % \ 703 "AA64FpDest" 704 header_output += FpRegRegOpDeclare.subst(fcvtFpFpHIop); 705 decoder_output += AA64FpRegRegOpConstructor.subst(fcvtFpFpHIop); 706 exec_output += BasicExecute.subst(fcvtFpFpHIop); 707 708 # Build the various versions of the floating point compare instructions 709 def buildFCmpOp(isQuiet, isDouble, isImm): 710 global header_output, decoder_output, exec_output 711 712 fcmpCode = vfp64EnabledCheckCode + ''' 713 FPSCR fpscr = (FPSCR) FpscrExc; 714 %s cOp1 = %s; 715 ''' % ("uint64_t" if isDouble else "uint32_t", 716 "AA64FpDestP0_uw | (uint64_t)AA64FpDestP1_uw << 32" 717 if isDouble else "AA64FpDestP0_uw") 718 if isImm: 719 fcmpCode += ''' 720 %s cOp2 = imm; 721 ''' % ("uint64_t" if isDouble else "uint32_t") 722 else: 723 fcmpCode += ''' 724 %s cOp2 = %s; 725 ''' % ("uint64_t" if isDouble else "uint32_t", 726 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 727 if isDouble else "AA64FpOp1P0_uw") 728 fcmpCode += ''' 729 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr); 730 CondCodesNZ = cc >> 2 & 3; 731 CondCodesC = cc >> 1 & 1; 732 CondCodesV = cc & 1; 733 FpCondCodes = fpscr & FpCondCodesMask; 734 FpscrExc = fpscr; 735 ''' % ("64" if isDouble else "32", "false" if isQuiet else "true") 736 737 typeName = "Imm" if isImm else "Reg" 738 instName = "FCmp%s%s%s" %("" if isQuiet else "E", typeName, 739 "D" if isDouble else "S") 740 fcmpIop = InstObjParams("fcmp%s" %("" if isQuiet else "e"), instName, 741 "FpReg%sOp" %(typeName), 742 {"code": fcmpCode, 743 "op_class": "FloatCmpOp"}, []) 744 745 declareTemp = eval("FpReg%sOpDeclare" %(typeName)); 746 constructorTemp = eval("AA64FpReg%sOpConstructor" %(typeName)); 747 header_output += declareTemp.subst(fcmpIop); 748 decoder_output += constructorTemp.subst(fcmpIop); 749 exec_output += BasicExecute.subst(fcmpIop); 750 751 for isQuiet in True, False: 752 for isDouble in True, False: 753 for isImm in True, False: 754 buildFCmpOp(isQuiet, isDouble, isImm) 755 756 # Build the various versions of the conditional floating point compare 757 # instructions 758 def buildFCCmpOp(isQuiet, isDouble): 759 global header_output, decoder_output, exec_output 760 761 fccmpCode = vfp64EnabledCheckCode + ''' 762 FPSCR fpscr = (FPSCR) FpscrExc; 763 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) { 764 %s cOp1 = %s; 765 %s cOp2 = %s; 766 int cc = fplibCompare<uint%s_t>(cOp1, cOp2, %s, fpscr); 767 CondCodesNZ = cc >> 2 & 3; 768 CondCodesC = cc >> 1 & 1; 769 CondCodesV = cc & 1; 770 } else { 771 CondCodesNZ = (defCc >> 2) & 0x3; 772 CondCodesC = (defCc >> 1) & 0x1; 773 CondCodesV = defCc & 0x1; 774 } 775 FpCondCodes = fpscr & FpCondCodesMask; 776 FpscrExc = fpscr; 777 ''' % ("uint64_t" if isDouble else "uint32_t", 778 "AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32" 779 if isDouble else "AA64FpOp1P0_uw", 780 "uint64_t" if isDouble else "uint32_t", 781 "AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32" 782 if isDouble else "AA64FpOp2P0_uw", 783 "64" if isDouble else "32", "false" if isQuiet else "true") 784 785 instName = "FCCmp%sReg%s" %("" if isQuiet else "E", 786 "D" if isDouble else "S") 787 fccmpIop = InstObjParams("fccmp%s" %("" if isQuiet else "e"), 788 instName, "FpCondCompRegOp", 789 {"code": fccmpCode, 790 "op_class": "FloatCmpOp"}, []) 791 header_output += DataXCondCompRegDeclare.subst(fccmpIop); 792 decoder_output += DataXCondCompRegConstructor.subst(fccmpIop); 793 exec_output += BasicExecute.subst(fccmpIop); 794 795 for isQuiet in True, False: 796 for isDouble in True, False: 797 buildFCCmpOp(isQuiet, isDouble) 798 799}}; 800 801let {{ 802 803 header_output = "" 804 decoder_output = "" 805 exec_output = "" 806 807 # Generates the variants of the floating to fixed point instructions 808 def buildFpCvtFixedOp(isSigned, isDouble, isXReg): 809 global header_output, decoder_output, exec_output 810 811 fcvtFpFixedCode = vfp64EnabledCheckCode + ''' 812 FPSCR fpscr = (FPSCR) FpscrExc; 813 ''' 814 if isDouble: 815 fcvtFpFixedCode += ''' 816 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 817 ''' 818 else: 819 fcvtFpFixedCode += "uint32_t cOp1 = AA64FpOp1P0_uw;" 820 fcvtFpFixedCode += ''' 821 %sDest = fplibFPToFixed<uint%s_t, uint%s_t>(cOp1, 64 - imm, %s, 822 FPRounding_ZERO, fpscr); 823 FpscrExc = fpscr; 824 ''' %("X" if isXReg else "W", 825 "64" if isDouble else "32", 826 "64" if isXReg else "32", 827 "false" if isSigned else "true") 828 829 instName = "FcvtFp%sFixed%s%s" %("S" if isSigned else "U", 830 "D" if isDouble else "S", 831 "X" if isXReg else "W") 832 mnem = "fcvtz%s" %("s" if isSigned else "u") 833 fcvtFpFixedIop = InstObjParams(mnem, instName, "FpRegRegImmOp", 834 { "code": fcvtFpFixedCode, 835 "op_class": "FloatCvtOp" }, []) 836 header_output += FpRegRegImmOpDeclare.subst(fcvtFpFixedIop); 837 decoder_output += AA64FpRegRegImmOpConstructor.subst(fcvtFpFixedIop); 838 exec_output += BasicExecute.subst(fcvtFpFixedIop); 839 840 # Generates the variants of the fixed to floating point instructions 841 def buildFixedCvtFpOp(isSigned, isDouble, isXReg): 842 global header_output, decoder_output, exec_output 843 844 srcRegType = "X" if isXReg else "W" 845 fcvtFixedFpCode = vfp64EnabledCheckCode + ''' 846 FPSCR fpscr = (FPSCR) FpscrExc; 847 %s result = fplibFixedToFP<uint%s_t>((%s%s_t)%sOp1, 64 - imm, 848 %s, FPCRRounding(fpscr), fpscr); 849 ''' %("uint64_t" if isDouble else "uint32_t", 850 "64" if isDouble else "32", 851 "int" if isSigned else "uint", "64" if isXReg else "32", 852 srcRegType, 853 "false" if isSigned else "true") 854 if isDouble: 855 fcvtFixedFpCode += ''' 856 AA64FpDestP0_uw = result; 857 AA64FpDestP1_uw = result >> 32; 858 ''' 859 else: 860 fcvtFixedFpCode += ''' 861 AA64FpDestP0_uw = result; 862 AA64FpDestP1_uw = 0; 863 ''' 864 fcvtFixedFpCode += ''' 865 AA64FpDestP2_uw = 0; 866 AA64FpDestP3_uw = 0; 867 FpscrExc = fpscr; 868 ''' 869 870 instName = "Fcvt%sFixedFp%s%s" %("S" if isSigned else "U", 871 "D" if isDouble else "S", 872 srcRegType) 873 mnem = "%scvtf" %("s" if isSigned else "u") 874 fcvtFixedFpIop = InstObjParams(mnem, instName, "FpRegRegImmOp", 875 { "code": fcvtFixedFpCode, 876 "op_class": "FloatCvtOp" }, []) 877 fcvtFixedFpIop.snippets["code"] += zeroSveVecRegUpperPartCode % \ 878 "AA64FpDest" 879 header_output += FpRegRegImmOpDeclare.subst(fcvtFixedFpIop); 880 decoder_output += FpRegRegImmOpConstructor.subst(fcvtFixedFpIop); 881 exec_output += BasicExecute.subst(fcvtFixedFpIop); 882 883 # loop over the variants building the instructions for each 884 for isXReg in True, False: 885 for isDouble in True, False: 886 for isSigned in True, False: 887 buildFpCvtFixedOp(isSigned, isDouble, isXReg) 888 buildFixedCvtFpOp(isSigned, isDouble, isXReg) 889}}; 890 891let {{ 892 893 header_output = "" 894 decoder_output = "" 895 exec_output = "" 896 897 for isDouble in True, False: 898 code = ''' 899 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) { 900 AA64FpDestP0_uw = AA64FpOp1P0_uw; 901 ''' 902 if isDouble: 903 code += ''' 904 AA64FpDestP1_uw = AA64FpOp1P1_uw; 905 } else { 906 AA64FpDestP0_uw = AA64FpOp2P0_uw; 907 AA64FpDestP1_uw = AA64FpOp2P1_uw; 908 } 909 ''' 910 else: 911 code += ''' 912 } else { 913 AA64FpDestP0_uw = AA64FpOp2P0_uw; 914 } 915 AA64FpDestP1_uw = 0; 916 ''' 917 code += ''' 918 AA64FpDestP2_uw = 0; 919 AA64FpDestP3_uw = 0; 920 ''' 921 922 iop = InstObjParams("fcsel", "FCSel%s" %("D" if isDouble else "S"), 923 "FpCondSelOp", { "code": code, 924 "op_class": "FloatCvtOp" }) 925 iop.snippets["code"] += zeroSveVecRegUpperPartCode % "AA64FpDest" 926 header_output += DataXCondSelDeclare.subst(iop) 927 decoder_output += DataXCondSelConstructor.subst(iop) 928 exec_output += BasicExecute.subst(iop) 929}}; 930