1// -*- C -*- 2 3// Simulator definition for the MIPS MDMX ASE. 4// Copyright (C) 2002-2023 Free Software Foundation, Inc. 5// Contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom 6// Corporation (SiByte). 7// 8// This file is part of GDB, the GNU debugger. 9// 10// This program is free software; you can redistribute it and/or modify 11// it under the terms of the GNU General Public License as published by 12// the Free Software Foundation; either version 3 of the License, or 13// (at your option) any later version. 14// 15// This program is distributed in the hope that it will be useful, 16// but WITHOUT ANY WARRANTY; without even the implied warranty of 17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18// GNU General Public License for more details. 19// 20// You should have received a copy of the GNU General Public License 21// along with this program. If not, see <http://www.gnu.org/licenses/>. 22 23// Reference: MIPS64 Architecture Volume IV-b: 24// The MDMX Application-Specific Extension 25 26// Notes on "format selectors" (FMTSEL): 27// 28// A selector with final bit 0 indicates OB format. 29// A selector with final bits 01 indicates QH format. 30// A selector with final bits 11 has UNPREDICTABLE result per the spec. 31// 32// Similarly, for the single-bit fields which differentiate between 33// formats (FMTOP), 0 is OB format and 1 is QH format. 34 35// If you change this file to add instructions, please make sure that model 36// "sb1" configurations still build, and that you've added no new 37// instructions to the "sb1" model. 38 39 40// Helper: 41// 42// Check whether MDMX is usable, and if not signal an appropriate exception. 43// 44 45:function:::void:check_mdmx:instruction_word insn 46*mdmx: 47{ 48 if (! COP_Usable (1)) 49 SignalExceptionCoProcessorUnusable (1); 50 if ((SR & (status_MX|status_FR)) != (status_MX|status_FR)) 51 SignalExceptionMDMX (); 52 check_u64 (SD_, insn); 53} 54 55 56// Helper: 57// 58// Check whether a given MDMX format selector indicates a valid and usable 59// format, and if not signal an appropriate exception. 60// 61 62:function:::int:check_mdmx_fmtsel:instruction_word insn, int fmtsel 63*mdmx: 64{ 65 switch (fmtsel & 0x03) 66 { 67 case 0x00: /* ob */ 68 case 0x02: 69 case 0x01: /* qh */ 70 return 1; 71 case 0x03: /* UNPREDICTABLE */ 72 SignalException (ReservedInstruction, insn); 73 return 0; 74 } 75 return 0; 76} 77 78 79// Helper: 80// 81// Check whether a given MDMX format bit indicates a valid and usable 82// format, and if not signal an appropriate exception. 83// 84 85:function:::int:check_mdmx_fmtop:instruction_word insn, int fmtop 86*mdmx: 87{ 88 switch (fmtop & 0x01) 89 { 90 case 0x00: /* ob */ 91 case 0x01: /* qh */ 92 return 1; 93 } 94 return 0; 95} 96 97 98:%s::::FMTSEL:int fmtsel 99*mdmx: 100*sb1: 101{ 102 if ((fmtsel & 0x1) == 0) 103 return "ob"; 104 else if ((fmtsel & 0x3) == 1) 105 return "qh"; 106 else 107 return "?"; 108} 109 110 111:%s::::FMTOP:int fmtop 112*mdmx: 113*sb1: 114{ 115 switch (fmtop) 116 { 117 case 0: return "ob"; 118 case 1: return "qh"; 119 default: return "?"; 120 } 121} 122 123 124:%s::::SHOP:int shop 125*mdmx: 126*sb1: 127{ 128 if ((shop & 0x11) == 0x00) 129 switch ((shop >> 1) & 0x07) 130 { 131 case 3: return "upsl.ob"; 132 case 4: return "pach.ob"; 133 case 6: return "mixh.ob"; 134 case 7: return "mixl.ob"; 135 default: return "?"; 136 } 137 else if ((shop & 0x03) == 0x01) 138 switch ((shop >> 2) & 0x07) 139 { 140 case 0: return "mixh.qh"; 141 case 1: return "mixl.qh"; 142 case 2: return "pach.qh"; 143 case 4: return "bfla.qh"; 144 case 6: return "repa.qh"; 145 case 7: return "repb.qh"; 146 default: return "?"; 147 } 148 else 149 return "?"; 150} 151 152 153011110,5.FMTSEL,5.VT,5.VS,5.VD,001011:MDMX:64::ADD.fmt 154"add.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 155*mdmx: 156*sb1: 157{ 158 check_mdmx (SD_, instruction_0); 159 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 160 StoreFPR(VD,fmt_mdmx,MX_Add(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 161} 162 163 164011110,5.FMTSEL,5.VT,5.VS,0,0000,110111:MDMX:64::ADDA.fmt 165"adda.%s<FMTSEL> v<VS>, v<VT>" 166*mdmx: 167*sb1: 168{ 169 check_mdmx (SD_, instruction_0); 170 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 171 MX_AddA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 172} 173 174 175011110,5.FMTSEL,5.VT,5.VS,1,0000,110111:MDMX:64::ADDL.fmt 176"addl.%s<FMTSEL> v<VS>, v<VT>" 177*mdmx: 178*sb1: 179{ 180 check_mdmx (SD_, instruction_0); 181 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 182 MX_AddL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 183} 184 185 186011110,00,3.IMM,5.VT,5.VS,5.VD,0110,1.FMTOP,0:MDMX:64::ALNI.fmt 187"alni.%s<FMTOP> v<VD>, v<VS>, v<VT>, <IMM>" 188*mdmx: 189*sb1: 190{ 191 uint64_t result; 192 int s; 193 check_mdmx (SD_, instruction_0); 194 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 195 s = (IMM << 3); 196 result = ValueFPR(VS,fmt_mdmx) << s; 197 if (s != 0) // x86 gcc treats >> 64 as >> 0 198 result |= ValueFPR(VT,fmt_mdmx) >> (64 - s); 199 StoreFPR(VD,fmt_mdmx,result); 200} 201 202 203011110,5.RS,5.VT,5.VS,5.VD,0110,1.FMTOP,1:MDMX:64::ALNV.fmt 204"alnv.%s<FMTOP> v<VD>, v<VS>, v<VT>, r<RS>" 205*mdmx: 206*sb1: 207{ 208 uint64_t result; 209 int s; 210 check_mdmx (SD_, instruction_0); 211 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 212 s = ((GPR[RS] & 0x7) << 3); 213 result = ValueFPR(VS,fmt_mdmx) << s; 214 if (s != 0) // x86 gcc treats >> 64 as >> 0 215 result |= ValueFPR(VT,fmt_mdmx) >> (64 - s); 216 StoreFPR(VD,fmt_mdmx,result); 217} 218 219 220011110,5.FMTSEL,5.VT,5.VS,5.VD,001100:MDMX:64::AND.fmt 221"and.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 222*mdmx: 223*sb1: 224{ 225 check_mdmx (SD_, instruction_0); 226 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 227 StoreFPR(VD,fmt_mdmx,MX_And(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 228} 229 230 231011110,5.FMTSEL,5.VT,5.VS,00000,000001:MDMX:64::C.EQ.fmt 232"c.eq.%s<FMTSEL> v<VS>, v<VT>" 233*mdmx: 234*sb1: 235{ 236 check_mdmx (SD_, instruction_0); 237 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 238 MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_EQ,VT,FMTSEL); 239} 240 241 242011110,5.FMTSEL,5.VT,5.VS,00000,000101:MDMX:64::C.LE.fmt 243"c.le.%s<FMTSEL> v<VS>, v<VT>" 244*mdmx: 245*sb1: 246{ 247 check_mdmx (SD_, instruction_0); 248 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 249 MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_LT|MX_C_EQ,VT,FMTSEL); 250} 251 252 253011110,5.FMTSEL,5.VT,5.VS,00000,000100:MDMX:64::C.LT.fmt 254"c.lt.%s<FMTSEL> v<VS>, v<VT>" 255*mdmx: 256*sb1: 257{ 258 check_mdmx (SD_, instruction_0); 259 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 260 MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_LT,VT,FMTSEL); 261} 262 263 264011110,5.FMTSEL,5.VT,5.VS,5.VD,000111:MDMX:64::MAX.fmt 265"max.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 266*mdmx: 267*sb1: 268{ 269 check_mdmx (SD_, instruction_0); 270 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 271 StoreFPR(VD,fmt_mdmx,MX_Max(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 272} 273 274 275011110,5.FMTSEL,5.VT,5.VS,5.VD,000110:MDMX:64::MIN.fmt 276"min.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 277*mdmx: 278*sb1: 279{ 280 check_mdmx (SD_, instruction_0); 281 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 282 StoreFPR(VD,fmt_mdmx,MX_Min(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 283} 284 285 286011110,3.SEL,01,5.VT,5.VS,5.VD,000000:MDMX:64::MSGN.QH 287"msgn.qh v<VD>, v<VS>, v<VT>" 288*mdmx: 289{ 290 check_mdmx (SD_, instruction_0); 291 StoreFPR(VD,fmt_mdmx,MX_Msgn(ValueFPR(VS,fmt_mdmx),VT,qh_fmtsel(SEL))); 292} 293 294 295011110,5.FMTSEL,5.VT,5.VS,5.VD,110000:MDMX:64::MUL.fmt 296"mul.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 297*mdmx: 298*sb1: 299{ 300 check_mdmx (SD_, instruction_0); 301 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 302 StoreFPR(VD,fmt_mdmx,MX_Mul(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 303} 304 305 306011110,5.FMTSEL,5.VT,5.VS,0,0000,110011:MDMX:64::MULA.fmt 307"mula.%s<FMTSEL> v<VS>, v<VT>" 308*mdmx: 309*sb1: 310{ 311 check_mdmx (SD_, instruction_0); 312 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 313 MX_MulA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 314} 315 316 317011110,5.FMTSEL,5.VT,5.VS,1,0000,110011:MDMX:64::MULL.fmt 318"mull.%s<FMTSEL> v<VS>, v<VT>" 319*mdmx: 320*sb1: 321{ 322 check_mdmx (SD_, instruction_0); 323 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 324 MX_MulL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 325} 326 327 328011110,5.FMTSEL,5.VT,5.VS,0,0000,110010:MDMX:64::MULS.fmt 329"muls.%s<FMTSEL> v<VS>, v<VT>" 330*mdmx: 331*sb1: 332{ 333 check_mdmx (SD_, instruction_0); 334 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 335 MX_MulS(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 336} 337 338 339011110,5.FMTSEL,5.VT,5.VS,1,0000,110010:MDMX:64::MULSL.fmt 340"mulsl.%s<FMTSEL> v<VS>, v<VT>" 341*mdmx: 342*sb1: 343{ 344 check_mdmx (SD_, instruction_0); 345 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 346 MX_MulSL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 347} 348 349 350011110,5.FMTSEL,5.VT,5.VS,5.VD,001111:MDMX:64::NOR.fmt 351"nor.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 352*mdmx: 353*sb1: 354{ 355 check_mdmx (SD_, instruction_0); 356 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 357 StoreFPR(VD,fmt_mdmx,MX_Nor(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 358} 359 360 361011110,5.FMTSEL,5.VT,5.VS,5.VD,001110:MDMX:64::OR.fmt 362"or.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 363*mdmx: 364*sb1: 365{ 366 check_mdmx (SD_, instruction_0); 367 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 368 StoreFPR(VD,fmt_mdmx,MX_Or(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 369} 370 371 372011110,5.FMTSEL,5.VT,5.VS,5.VD,000010:MDMX:64::PICKF.fmt 373"pickf.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 374*mdmx: 375*sb1: 376{ 377 check_mdmx (SD_, instruction_0); 378 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 379 StoreFPR(VD,fmt_mdmx,MX_Pick(0,ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 380} 381 382 383011110,5.FMTSEL,5.VT,5.VS,5.VD,000011:MDMX:64::PICKT.fmt 384"pickt.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 385*mdmx: 386*sb1: 387{ 388 check_mdmx (SD_, instruction_0); 389 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 390 StoreFPR(VD,fmt_mdmx,MX_Pick(1,ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 391} 392 393 394011110,1000,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACH.fmt 395"rach.%s<FMTOP> v<VD>" 396*mdmx: 397*sb1: 398{ 399 check_mdmx (SD_, instruction_0); 400 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 401 StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_H,FMTOP)); 402} 403 404 405011110,0000,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACL.fmt 406"racl.%s<FMTOP> v<VD>" 407*mdmx: 408*sb1: 409{ 410 check_mdmx (SD_, instruction_0); 411 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 412 StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_L,FMTOP)); 413} 414 415 416011110,0100,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACM.fmt 417"racm.%s<FMTOP> v<VD>" 418*mdmx: 419*sb1: 420{ 421 check_mdmx (SD_, instruction_0); 422 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 423 StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_M,FMTOP)); 424} 425 426 427011110,3.SEL,01,5.VT,00000,5.VD,100101:MDMX:64::RNAS.QH 428"rnas.qh v<VD>, v<VT>" 429*mdmx: 430{ 431 check_mdmx (SD_, instruction_0); 432 StoreFPR(VD,fmt_mdmx,MX_RNAS(VT,qh_fmtsel(SEL))); 433} 434 435 436011110,5.FMTSEL,5.VT,00000,5.VD,100001:MDMX:64::RNAU.fmt 437"rnau.%s<FMTSEL> v<VD>, v<VT>" 438*mdmx: 439*sb1: 440{ 441 check_mdmx (SD_, instruction_0); 442 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 443 StoreFPR(VD,fmt_mdmx,MX_RNAU(VT,FMTSEL)); 444} 445 446 447011110,3.SEL,01,5.VT,00000,5.VD,100110:MDMX:64::RNES.QH 448"rnes.qh v<VD>, v<VT>" 449*mdmx: 450{ 451 check_mdmx (SD_, instruction_0); 452 StoreFPR(VD,fmt_mdmx,MX_RNES(VT,qh_fmtsel(SEL))); 453} 454 455 456011110,5.FMTSEL,5.VT,00000,5.VD,100010:MDMX:64::RNEU.fmt 457"rneu.%s<FMTSEL> v<VD>, v<VT>" 458*mdmx: 459*sb1: 460{ 461 check_mdmx (SD_, instruction_0); 462 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 463 StoreFPR(VD,fmt_mdmx,MX_RNEU(VT,FMTSEL)); 464} 465 466 467011110,3.SEL,01,5.VT,00000,5.VD,100100:MDMX:64::RZS.QH 468"rzs.qh v<VD>, v<VT>" 469*mdmx: 470{ 471 check_mdmx (SD_, instruction_0); 472 StoreFPR(VD,fmt_mdmx,MX_RZS(VT,qh_fmtsel(SEL))); 473} 474 475 476011110,5.FMTSEL,5.VT,00000,5.VD,100000:MDMX:64::RZU.fmt 477"rzu.%s<FMTSEL> v<VD>, v<VT>" 478*mdmx: 479*sb1: 480{ 481 check_mdmx (SD_, instruction_0); 482 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 483 StoreFPR(VD,fmt_mdmx,MX_RZU(VT,FMTSEL)); 484} 485 486 487011110,5.SHOP,5.VT,5.VS,5.VD,011111:MDMX:64::SHFL.op.fmt 488"shfl.%s<SHOP> v<VD>, v<VS>, v<VT>" 489*mdmx: 490*sb1: 491{ 492 check_mdmx (SD_, instruction_0); 493 if (check_mdmx_fmtsel (SD_, instruction_0, SHOP)) 494 StoreFPR(VD,fmt_mdmx,MX_SHFL(SHOP,ValueFPR(VS,fmt_mdmx),ValueFPR(VT,fmt_mdmx))); 495} 496 497 498011110,5.FMTSEL,5.VT,5.VS,5.VD,010000:MDMX:64::SLL.fmt 499"sll.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 500*mdmx: 501*sb1: 502{ 503 check_mdmx (SD_, instruction_0); 504 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 505 StoreFPR(VD,fmt_mdmx,MX_ShiftLeftLogical(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 506} 507 508 509011110,3.SEL,01,5.VT,5.VS,5.VD,010011:MDMX:64::SRA.QH 510"sra.qh v<VD>, v<VS>, v<VT>" 511*mdmx: 512{ 513 check_mdmx (SD_, instruction_0); 514 StoreFPR(VD,fmt_mdmx,MX_ShiftRightArith(ValueFPR(VS,fmt_mdmx),VT,qh_fmtsel(SEL))); 515} 516 517 518011110,5.FMTSEL,5.VT,5.VS,5.VD,010010:MDMX:64::SRL.fmt 519"srl.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 520*mdmx: 521*sb1: 522{ 523 check_mdmx (SD_, instruction_0); 524 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 525 StoreFPR(VD,fmt_mdmx,MX_ShiftRightLogical(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 526} 527 528 529011110,5.FMTSEL,5.VT,5.VS,5.VD,001010:MDMX:64::SUB.fmt 530"sub.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 531*mdmx: 532*sb1: 533{ 534 check_mdmx (SD_, instruction_0); 535 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 536 StoreFPR(VD,fmt_mdmx,MX_Sub(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 537} 538 539 540011110,5.FMTSEL,5.VT,5.VS,0,0000,110110:MDMX:64::SUBA.fmt 541"suba.%s<FMTSEL> v<VS>, v<VT>" 542*mdmx: 543*sb1: 544{ 545 check_mdmx (SD_, instruction_0); 546 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 547 MX_SubA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 548} 549 550 551011110,5.FMTSEL,5.VT,5.VS,1,0000,110110:MDMX:64::SUBL.fmt 552"subl.%s<FMTSEL> v<VS>, v<VT>" 553*mdmx: 554*sb1: 555{ 556 check_mdmx (SD_, instruction_0); 557 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 558 MX_SubL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL); 559} 560 561 562011110,1000,1.FMTOP,00000,5.VS,00000,111110:MDMX:64::WACH.fmt 563"wach.%s<FMTOP> v<VS>" 564*mdmx: 565*sb1: 566{ 567 check_mdmx (SD_, instruction_0); 568 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 569 MX_WACH(FMTOP,ValueFPR(VS,fmt_mdmx)); 570} 571 572 573011110,0000,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WACL.fmt 574"wacl.%s<FMTOP> v<VS>, v<VT>" 575*mdmx: 576*sb1: 577{ 578 check_mdmx (SD_, instruction_0); 579 check_mdmx_fmtop (SD_, instruction_0, FMTOP); 580 MX_WACL(FMTOP,ValueFPR(VS,fmt_mdmx),ValueFPR(VT,fmt_mdmx)); 581} 582 583 584011110,5.FMTSEL,5.VT,5.VS,5.VD,001101:MDMX:64::XOR.fmt 585"xor.%s<FMTSEL> v<VD>, v<VS>, v<VT>" 586*mdmx: 587*sb1: 588{ 589 check_mdmx (SD_, instruction_0); 590 if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL)) 591 StoreFPR(VD,fmt_mdmx,MX_Xor(ValueFPR(VS,fmt_mdmx),VT,FMTSEL)); 592} 593