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 --- 155 unchanged lines hidden (view full) --- 167}}; 168 169let {{ 170 171 header_output = "" 172 decoder_output = "" 173 exec_output = "" 174 |
175 halfIntConvCode = vfp64EnabledCheckCode + ''' 176 FPSCR fpscr = (FPSCR) FpscrExc; 177 uint16_t cOp1 = AA64FpOp1P0_uw; 178 uint16_t cDest = %(op)s; 179 AA64FpDestP0_uw = cDest; 180 AA64FpDestP1_uw = 0; 181 AA64FpDestP2_uw = 0; 182 AA64FpDestP3_uw = 0; 183 FpscrExc = fpscr; 184 ''' 185 186 halfIntConvCode2 = vfp64EnabledCheckCode + ''' 187 FPSCR fpscr = (FPSCR) FpscrExc; 188 uint16_t cOp1 = AA64FpOp1P0_uw; 189 uint16_t cOp2 = AA64FpOp2P0_uw; 190 uint16_t cDest = %(op)s; 191 AA64FpDestP0_uw = cDest; 192 AA64FpDestP1_uw = 0; 193 AA64FpDestP2_uw = 0; 194 AA64FpDestP3_uw = 0; 195 FpscrExc = fpscr; 196 ''' 197 198 halfBinOp = "binaryOp(fpscr, AA64FpOp1P0, AA64FpOp2P0," + \ 199 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" 200 halfUnaryOp = "unaryOp(fpscr, AA64FpOp1P0," + \ 201 "%(func)s, fpscr.fz, fpscr.rMode)" 202 |
203 singleIntConvCode = vfp64EnabledCheckCode + ''' 204 FPSCR fpscr = (FPSCR) FpscrExc; 205 uint32_t cOp1 = AA64FpOp1P0_uw; 206 uint32_t cDest = %(op)s; 207 AA64FpDestP0_uw = cDest; 208 AA64FpDestP1_uw = 0; 209 AA64FpDestP2_uw = 0; 210 AA64FpDestP3_uw = 0; --- 44 unchanged lines hidden (view full) --- 255 dbl(AA64FpOp2P0_uw, AA64FpOp2P1_uw), 256 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode); 257 ''' 258 doubleUnaryOp = ''' 259 unaryOp(fpscr, dbl(AA64FpOp1P0_uw, AA64FpOp1P1_uw), %(func)s, 260 fpscr.fz, fpscr.rMode) 261 ''' 262 |
263 def buildTernaryFpOp(name, opClass, hOp, sOp, dOp): |
264 global header_output, decoder_output, exec_output |
265 for suffix in "D", "S", "H": |
266 code = vfp64EnabledCheckCode + ''' 267 FPSCR fpscr = (FPSCR) FpscrExc; 268 ''' |
269 if suffix == "H": |
270 code += ''' |
271 uint16_t cOp1 = AA64FpOp1P0_uw; 272 uint16_t cOp2 = AA64FpOp2P0_uw; 273 uint16_t cOp3 = AA64FpOp3P0_uw; 274 uint16_t cDest; 275 ''' "cDest = " + hOp + ";" + ''' |
276 AA64FpDestP0_uw = cDest; |
277 AA64FpDestP1_uw = 0; |
278 ''' |
279 elif suffix == "S": |
280 code += ''' 281 uint32_t cOp1 = AA64FpOp1P0_uw; 282 uint32_t cOp2 = AA64FpOp2P0_uw; 283 uint32_t cOp3 = AA64FpOp3P0_uw; 284 uint32_t cDest; 285 ''' "cDest = " + sOp + ";" + ''' 286 AA64FpDestP0_uw = cDest; 287 AA64FpDestP1_uw = 0; 288 ''' |
289 elif suffix == "D": 290 code += ''' 291 uint64_t cOp1 = AA64FpOp1P0_uw | (uint64_t)AA64FpOp1P1_uw << 32; 292 uint64_t cOp2 = AA64FpOp2P0_uw | (uint64_t)AA64FpOp2P1_uw << 32; 293 uint64_t cOp3 = AA64FpOp3P0_uw | (uint64_t)AA64FpOp3P1_uw << 32; 294 uint64_t cDest; 295 ''' "cDest = " + dOp + ";" + ''' 296 AA64FpDestP0_uw = cDest; 297 AA64FpDestP1_uw = cDest >> 32; 298 ''' |
299 code += ''' 300 AA64FpDestP2_uw = 0; 301 AA64FpDestP3_uw = 0; 302 FpscrExc = fpscr; 303 ''' 304 |
305 iop = InstObjParams(name.lower(), name + suffix, |
306 "FpRegRegRegRegOp", 307 { "code": code, "op_class": opClass }, []) 308 309 header_output += AA64FpRegRegRegRegOpDeclare.subst(iop) 310 decoder_output += AA64FpRegRegRegRegOpConstructor.subst(iop) 311 exec_output += BasicExecute.subst(iop) 312 313 buildTernaryFpOp("FMAdd", "FloatMultAccOp", |
314 "fplibMulAdd<uint16_t>(cOp3, cOp1, cOp2, fpscr)", |
315 "fplibMulAdd<uint32_t>(cOp3, cOp1, cOp2, fpscr)", 316 "fplibMulAdd<uint64_t>(cOp3, cOp1, cOp2, fpscr)" ) 317 buildTernaryFpOp("FMSub", "FloatMultAccOp", |
318 "fplibMulAdd<uint16_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 319 "fplibMulAdd<uint32_t>(cOp3, fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 320 "fplibMulAdd<uint64_t>(cOp3, fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" ) |
321 buildTernaryFpOp("FNMAdd", "FloatMultAccOp", |
322 "fplibMulAdd<uint16_t>(fplibNeg<uint16_t>(cOp3), " + 323 "fplibNeg<uint16_t>(cOp1), cOp2, fpscr)", 324 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), " + 325 "fplibNeg<uint32_t>(cOp1), cOp2, fpscr)", 326 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), " + 327 "fplibNeg<uint64_t>(cOp1), cOp2, fpscr)" ) |
328 buildTernaryFpOp("FNMSub", "FloatMultAccOp", |
329 "fplibMulAdd<uint16_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)", 330 "fplibMulAdd<uint32_t>(fplibNeg<uint32_t>(cOp3), cOp1, cOp2, fpscr)", 331 "fplibMulAdd<uint64_t>(fplibNeg<uint64_t>(cOp3), cOp1, cOp2, fpscr)" ) |
332 |
333 def buildBinFpOp(name, Name, base, opClass, halfOp, singleOp, doubleOp): |
334 global header_output, decoder_output, exec_output 335 |
336 code = halfIntConvCode2 % { "op": halfOp } 337 hIop = InstObjParams(name, Name + "H", base, 338 { "code": code, 339 "op_class": opClass }, []) 340 |
341 code = singleIntConvCode2 % { "op": singleOp } 342 sIop = InstObjParams(name, Name + "S", base, 343 { "code": code, 344 "op_class": opClass }, []) 345 346 code = doubleIntConvCode2 % { "op": doubleOp } 347 dIop = InstObjParams(name, Name + "D", base, 348 { "code": code, 349 "op_class": opClass }, []) 350 351 declareTempl = eval( base + "Declare"); 352 constructorTempl = eval("AA64" + base + "Constructor"); 353 |
354 for iop in hIop, sIop, dIop: |
355 header_output += declareTempl.subst(iop) 356 decoder_output += constructorTempl.subst(iop) 357 exec_output += BasicExecute.subst(iop) 358 359 buildBinFpOp("fadd", "FAdd", "FpRegRegRegOp", "FloatAddOp", |
360 "fplibAdd<uint16_t>(cOp1, cOp2, fpscr)", |
361 "fplibAdd<uint32_t>(cOp1, cOp2, fpscr)", 362 "fplibAdd<uint64_t>(cOp1, cOp2, fpscr)") 363 buildBinFpOp("fsub", "FSub", "FpRegRegRegOp", "FloatAddOp", |
364 "fplibSub<uint16_t>(cOp1, cOp2, fpscr)", |
365 "fplibSub<uint32_t>(cOp1, cOp2, fpscr)", 366 "fplibSub<uint64_t>(cOp1, cOp2, fpscr)") 367 buildBinFpOp("fdiv", "FDiv", "FpRegRegRegOp", "FloatDivOp", |
368 "fplibDiv<uint16_t>(cOp1, cOp2, fpscr)", |
369 "fplibDiv<uint32_t>(cOp1, cOp2, fpscr)", 370 "fplibDiv<uint64_t>(cOp1, cOp2, fpscr)") 371 buildBinFpOp("fmul", "FMul", "FpRegRegRegOp", "FloatMultOp", |
372 "fplibMul<uint16_t>(cOp1, cOp2, fpscr)", |
373 "fplibMul<uint32_t>(cOp1, cOp2, fpscr)", 374 "fplibMul<uint64_t>(cOp1, cOp2, fpscr)") 375 buildBinFpOp("fnmul", "FNMul", "FpRegRegRegOp", "FloatMultOp", |
376 "fplibNeg<uint16_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))", |
377 "fplibNeg<uint32_t>(fplibMul<uint32_t>(cOp1, cOp2, fpscr))", 378 "fplibNeg<uint64_t>(fplibMul<uint64_t>(cOp1, cOp2, fpscr))") 379 buildBinFpOp("fmin", "FMin", "FpRegRegRegOp", "FloatCmpOp", |
380 "fplibMin<uint16_t>(cOp1, cOp2, fpscr)", |
381 "fplibMin<uint32_t>(cOp1, cOp2, fpscr)", 382 "fplibMin<uint64_t>(cOp1, cOp2, fpscr)") 383 buildBinFpOp("fmax", "FMax", "FpRegRegRegOp", "FloatCmpOp", |
384 "fplibMax<uint16_t>(cOp1, cOp2, fpscr)", |
385 "fplibMax<uint32_t>(cOp1, cOp2, fpscr)", 386 "fplibMax<uint64_t>(cOp1, cOp2, fpscr)") 387 buildBinFpOp("fminnm", "FMinNM", "FpRegRegRegOp", "FloatCmpOp", |
388 "fplibMinNum<uint16_t>(cOp1, cOp2, fpscr)", |
389 "fplibMinNum<uint32_t>(cOp1, cOp2, fpscr)", 390 "fplibMinNum<uint64_t>(cOp1, cOp2, fpscr)") 391 buildBinFpOp("fmaxnm", "FMaxNM", "FpRegRegRegOp", "FloatCmpOp", |
392 "fplibMaxNum<uint16_t>(cOp1, cOp2, fpscr)", |
393 "fplibMaxNum<uint32_t>(cOp1, cOp2, fpscr)", 394 "fplibMaxNum<uint64_t>(cOp1, cOp2, fpscr)") 395 |
396 def buildUnaryFpOp(name, Name, base, opClass, 397 halfOp, singleOp, doubleOp = None): |
398 if doubleOp is None: 399 doubleOp = singleOp 400 global header_output, decoder_output, exec_output 401 |
402 code = halfIntConvCode % { "op": halfOp } 403 hIop = InstObjParams(name, Name + "H", base, 404 { "code": code, 405 "op_class": opClass }, []) |
406 code = singleIntConvCode % { "op": singleOp } 407 sIop = InstObjParams(name, Name + "S", base, 408 { "code": code, 409 "op_class": opClass }, []) 410 code = doubleIntConvCode % { "op": doubleOp } 411 dIop = InstObjParams(name, Name + "D", base, 412 { "code": code, 413 "op_class": opClass }, []) 414 415 declareTempl = eval( base + "Declare"); 416 constructorTempl = eval("AA64" + base + "Constructor"); 417 |
418 for iop in hIop, sIop, dIop: |
419 header_output += declareTempl.subst(iop) 420 decoder_output += constructorTempl.subst(iop) 421 exec_output += BasicExecute.subst(iop) 422 423 buildUnaryFpOp("fsqrt", "FSqrt", "FpRegRegOp", "FloatSqrtOp", |
424 "fplibSqrt<uint16_t>(cOp1, fpscr)", 425 "fplibSqrt<uint32_t>(cOp1, fpscr)", 426 "fplibSqrt<uint64_t>(cOp1, fpscr)") |
427 |
428 def buildSimpleUnaryFpOp(name, Name, base, opClass, halfOp, singleOp, |
429 doubleOp = None, isIntConv = True): 430 if doubleOp is None: 431 doubleOp = singleOp 432 global header_output, decoder_output, exec_output 433 434 if isIntConv: |
435 hCode = halfIntConvCode |
436 sCode = singleIntConvCode 437 dCode = doubleIntConvCode 438 else: |
439 hCode = halfCode |
440 sCode = singleCode 441 dCode = doubleCode 442 |
443 for code, op, suffix in [[hCode, halfOp, "H"], 444 [sCode, singleOp, "S"], |
445 [dCode, doubleOp, "D"]]: 446 iop = InstObjParams(name, Name + suffix, base, 447 { "code": code % { "op": op }, 448 "op_class": opClass }, []) 449 450 declareTempl = eval( base + "Declare"); 451 constructorTempl = eval("AA64" + base + "Constructor"); 452 453 header_output += declareTempl.subst(iop) 454 decoder_output += constructorTempl.subst(iop) 455 exec_output += BasicExecute.subst(iop) 456 457 buildSimpleUnaryFpOp("fneg", "FNeg", "FpRegRegOp", "FloatMiscOp", |
458 "fplibNeg<uint16_t>(cOp1)", 459 "fplibNeg<uint32_t>(cOp1)", 460 "fplibNeg<uint64_t>(cOp1)") |
461 buildSimpleUnaryFpOp("fabs", "FAbs", "FpRegRegOp", "FloatMiscOp", |
462 "fplibAbs<uint16_t>(cOp1)", 463 "fplibAbs<uint32_t>(cOp1)", 464 "fplibAbs<uint64_t>(cOp1)") |
465 buildSimpleUnaryFpOp("frintn", "FRIntN", "FpRegRegOp", "FloatMiscOp", |
466 "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)", 467 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)", 468 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEEVEN, false, fpscr)") |
469 buildSimpleUnaryFpOp("frintp", "FRIntP", "FpRegRegOp", "FloatMiscOp", |
470 "fplibRoundInt<uint16_t>(cOp1, FPRounding_POSINF, false, fpscr)", 471 "fplibRoundInt<uint32_t>(cOp1, FPRounding_POSINF, false, fpscr)", 472 "fplibRoundInt<uint64_t>(cOp1, FPRounding_POSINF, false, fpscr)") |
473 buildSimpleUnaryFpOp("frintm", "FRIntM", "FpRegRegOp", "FloatMiscOp", |
474 "fplibRoundInt<uint16_t>(cOp1, FPRounding_NEGINF, false, fpscr)", 475 "fplibRoundInt<uint32_t>(cOp1, FPRounding_NEGINF, false, fpscr)", 476 "fplibRoundInt<uint64_t>(cOp1, FPRounding_NEGINF, false, fpscr)") |
477 buildSimpleUnaryFpOp("frintz", "FRIntZ", "FpRegRegOp", "FloatMiscOp", |
478 "fplibRoundInt<uint16_t>(cOp1, FPRounding_ZERO, false, fpscr)", 479 "fplibRoundInt<uint32_t>(cOp1, FPRounding_ZERO, false, fpscr)", 480 "fplibRoundInt<uint64_t>(cOp1, FPRounding_ZERO, false, fpscr)") |
481 buildSimpleUnaryFpOp("frinta", "FRIntA", "FpRegRegOp", "FloatMiscOp", |
482 "fplibRoundInt<uint16_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)", 483 "fplibRoundInt<uint32_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)", 484 "fplibRoundInt<uint64_t>(cOp1, FPRounding_TIEAWAY, false, fpscr)") |
485 buildSimpleUnaryFpOp("frinti", "FRIntI", "FpRegRegOp", "FloatMiscOp", |
486 "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), false, fpscr)", 487 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), false, fpscr)", 488 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), false, fpscr)") |
489 buildSimpleUnaryFpOp("frintx", "FRIntX", "FpRegRegOp", "FloatMiscOp", |
490 "fplibRoundInt<uint16_t>(cOp1, FPCRRounding(fpscr), true, fpscr)", 491 "fplibRoundInt<uint32_t>(cOp1, FPCRRounding(fpscr), true, fpscr)", 492 "fplibRoundInt<uint64_t>(cOp1, FPCRRounding(fpscr), true, fpscr)") |
493}}; 494 495let {{ 496 497 header_output = "" 498 decoder_output = "" 499 exec_output = "" 500 --- 394 unchanged lines hidden --- |