1/* Tests the multiply instructions. 2 3 Copyright (C) 2017-2023 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18# mach: or1k 19# output: report(0x00000002);\n 20# output: report(0x00000003);\n 21# output: report(0x00000006);\n 22# output: report(0x00000000);\n 23# output: report(0x00000000);\n 24# output: report(0x00000000);\n 25# output: \n 26# output: report(0x00008001);\n 27# output: report(0x0000fffe);\n 28# output: report(0x7ffffffe);\n 29# output: report(0x00000000);\n 30# output: report(0x00000000);\n 31# output: report(0x00000000);\n 32# output: \n 33# output: report(0x00008000);\n 34# output: report(0x00010000);\n 35# output: report(0x80000000);\n 36# output: report(0x00000000);\n 37# output: report(0x00000001);\n 38# output: report(0x00000000);\n 39# output: \n 40# output: report(0x00010000);\n 41# output: report(0x00010000);\n 42# output: report(0x00000000);\n 43# output: report(0x00000000);\n 44# output: report(0x00000001);\n 45# output: report(0x00000000);\n 46# output: \n 47# output: report(0xfffffffe);\n 48# output: report(0xfffffffd);\n 49# output: report(0x00000006);\n 50# output: report(0x00000000);\n 51# output: report(0x00000000);\n 52# output: report(0x00000000);\n 53# output: \n 54# output: report(0xffff7fff);\n 55# output: report(0xffff0002);\n 56# output: report(0x7ffffffe);\n 57# output: report(0x00000000);\n 58# output: report(0x00000000);\n 59# output: report(0x00000000);\n 60# output: \n 61# output: report(0xffff7fff);\n 62# output: report(0xffff0000);\n 63# output: report(0x80010000);\n 64# output: report(0x00000000);\n 65# output: report(0x00000001);\n 66# output: report(0x00000000);\n 67# output: \n 68# output: report(0xffff0000);\n 69# output: report(0xfffeffff);\n 70# output: report(0x00010000);\n 71# output: report(0x00000000);\n 72# output: report(0x00000001);\n 73# output: report(0x00000000);\n 74# output: \n 75# output: report(0x00000002);\n 76# output: report(0xfffffffd);\n 77# output: report(0xfffffffa);\n 78# output: report(0x00000000);\n 79# output: report(0x00000000);\n 80# output: report(0x00000000);\n 81# output: \n 82# output: report(0xffff8000);\n 83# output: report(0x00010000);\n 84# output: report(0x80000000);\n 85# output: report(0x00000000);\n 86# output: report(0x00000000);\n 87# output: report(0x00000000);\n 88# output: \n 89# output: report(0xffff7fff);\n 90# output: report(0x00010000);\n 91# output: report(0x7fff0000);\n 92# output: report(0x00000000);\n 93# output: report(0x00000001);\n 94# output: report(0x00000000);\n 95# output: \n 96# output: report(0x80000000);\n 97# output: report(0x00000001);\n 98# output: report(0x80000000);\n 99# output: report(0x00000000);\n 100# output: report(0x00000000);\n 101# output: report(0x00000000);\n 102# output: \n 103# output: report(0x00008000);\n 104# output: report(0x00010000);\n 105# output: report(0x80000000);\n 106# output: report(0x00000000);\n 107# output: report(0x00000001);\n 108# output: report(0x00000001);\n 109# output: \n 110# output: report(0x00000002);\n 111# output: report(0xfffffffd);\n 112# output: report(0xfffffffa);\n 113# output: report(0x00000000);\n 114# output: report(0x00000000);\n 115# output: report(0x00000000);\n 116# output: \n 117# output: report(0xffff7fff);\n 118# output: report(0xffff0000);\n 119# output: report(0x80010000);\n 120# output: report(0x00000000);\n 121# output: report(0x00000001);\n 122# output: report(0x00000001);\n 123# output: \n 124# output: report(0x00000002);\n 125# output: report(0x00000003);\n 126# output: report(0x00000006);\n 127# output: report(0x00000000);\n 128# output: report(0x00000000);\n 129# output: report(0x00000000);\n 130# output: \n 131# output: report(0x00010002);\n 132# output: report(0x00007fff);\n 133# output: report(0x7ffffffe);\n 134# output: report(0x00000000);\n 135# output: report(0x00000000);\n 136# output: report(0x00000000);\n 137# output: \n 138# output: report(0x00020000);\n 139# output: report(0x00004000);\n 140# output: report(0x80000000);\n 141# output: report(0x00000000);\n 142# output: report(0x00000001);\n 143# output: report(0x00000000);\n 144# output: \n 145# output: report(0x00040000);\n 146# output: report(0x00004000);\n 147# output: report(0x00000000);\n 148# output: report(0x00000000);\n 149# output: report(0x00000001);\n 150# output: report(0x00000000);\n 151# output: \n 152# output: report(0xfffffffe);\n 153# output: report(0x0000fffd);\n 154# output: report(0x00000006);\n 155# output: report(0x00000000);\n 156# output: report(0x00000000);\n 157# output: report(0x00000000);\n 158# output: \n 159# output: report(0xfffefffe);\n 160# output: report(0x00008001);\n 161# output: report(0x7ffffffe);\n 162# output: report(0x00000000);\n 163# output: report(0x00000000);\n 164# output: report(0x00000000);\n 165# output: \n 166# output: report(0xfffe0000);\n 167# output: report(0x0000bfff);\n 168# output: report(0x80020000);\n 169# output: report(0x00000000);\n 170# output: report(0x00000001);\n 171# output: report(0x00000000);\n 172# output: \n 173# output: report(0xfffdfffe);\n 174# output: report(0x00008000);\n 175# output: report(0x00010000);\n 176# output: report(0x00000000);\n 177# output: report(0x00000001);\n 178# output: report(0x00000000);\n 179# output: \n 180# output: report(0x00000002);\n 181# output: report(0x0000fffd);\n 182# output: report(0xfffffffa);\n 183# output: report(0x00000000);\n 184# output: report(0x00000000);\n 185# output: report(0x00000000);\n 186# output: \n 187# output: report(0x00010000);\n 188# output: report(0x00008000);\n 189# output: report(0x80000000);\n 190# output: report(0x00000000);\n 191# output: report(0x00000000);\n 192# output: report(0x00000000);\n 193# output: \n 194# output: report(0xfffdfffc);\n 195# output: report(0x00004000);\n 196# output: report(0x7fff0000);\n 197# output: report(0x00000000);\n 198# output: report(0x00000001);\n 199# output: report(0x00000000);\n 200# output: \n 201# output: report(0x80000000);\n 202# output: report(0x00000001);\n 203# output: report(0x80000000);\n 204# output: report(0x00000000);\n 205# output: report(0x00000000);\n 206# output: report(0x00000000);\n 207# output: \n 208# output: report(0x00020000);\n 209# output: report(0x00004000);\n 210# output: report(0x80000000);\n 211# output: report(0x00000000);\n 212# output: report(0x00000001);\n 213# output: report(0x00000001);\n 214# output: \n 215# output: report(0xfffffffe);\n 216# output: report(0x0000fffd);\n 217# output: report(0x00000006);\n 218# output: report(0x00000000);\n 219# output: report(0x00000000);\n 220# output: report(0x00000000);\n 221# output: \n 222# output: report(0xfffdfffe);\n 223# output: report(0x00008000);\n 224# output: report(0x00010000);\n 225# output: report(0x00000000);\n 226# output: report(0x00000001);\n 227# output: report(0x00000001);\n 228# output: \n 229# output: report(0x00000002);\n 230# output: report(0x00000003);\n 231# output: report(0x00000006);\n 232# output: report(0x00000000);\n 233# output: report(0x00000000);\n 234# output: report(0x00000000);\n 235# output: \n 236# output: report(0x00008001);\n 237# output: report(0x0000fffe);\n 238# output: report(0x7ffffffe);\n 239# output: report(0x00000000);\n 240# output: report(0x00000000);\n 241# output: report(0x00000000);\n 242# output: \n 243# output: report(0x00008000);\n 244# output: report(0x00010000);\n 245# output: report(0x80000000);\n 246# output: report(0x00000000);\n 247# output: report(0x00000000);\n 248# output: report(0x00000000);\n 249# output: \n 250# output: report(0x00010000);\n 251# output: report(0x00010000);\n 252# output: report(0x00000000);\n 253# output: report(0x00000001);\n 254# output: report(0x00000000);\n 255# output: report(0x00000000);\n 256# output: \n 257# output: report(0xfffffffe);\n 258# output: report(0xfffffffd);\n 259# output: report(0x00000006);\n 260# output: report(0x00000001);\n 261# output: report(0x00000000);\n 262# output: report(0x00000000);\n 263# output: \n 264# output: report(0xffff7fff);\n 265# output: report(0xffff0002);\n 266# output: report(0x7ffffffe);\n 267# output: report(0x00000001);\n 268# output: report(0x00000000);\n 269# output: report(0x00000000);\n 270# output: \n 271# output: report(0xffff7fff);\n 272# output: report(0xffff0000);\n 273# output: report(0x80010000);\n 274# output: report(0x00000001);\n 275# output: report(0x00000000);\n 276# output: report(0x00000000);\n 277# output: \n 278# output: report(0xffff0000);\n 279# output: report(0xfffeffff);\n 280# output: report(0x00010000);\n 281# output: report(0x00000001);\n 282# output: report(0x00000000);\n 283# output: report(0x00000000);\n 284# output: \n 285# output: report(0x00000002);\n 286# output: report(0xfffffffd);\n 287# output: report(0xfffffffa);\n 288# output: report(0x00000001);\n 289# output: report(0x00000000);\n 290# output: report(0x00000000);\n 291# output: \n 292# output: report(0xffff8000);\n 293# output: report(0x00010000);\n 294# output: report(0x80000000);\n 295# output: report(0x00000001);\n 296# output: report(0x00000000);\n 297# output: report(0x00000000);\n 298# output: \n 299# output: report(0xffff7fff);\n 300# output: report(0x00010000);\n 301# output: report(0x7fff0000);\n 302# output: report(0x00000001);\n 303# output: report(0x00000000);\n 304# output: report(0x00000000);\n 305# output: \n 306# output: report(0x80000000);\n 307# output: report(0x00000001);\n 308# output: report(0x80000000);\n 309# output: report(0x00000000);\n 310# output: report(0x00000000);\n 311# output: report(0x00000000);\n 312# output: \n 313# output: report(0x00008000);\n 314# output: report(0x00010000);\n 315# output: report(0x80000000);\n 316# output: report(0x00000000);\n 317# output: report(0x00000000);\n 318# output: report(0x00000000);\n 319# output: \n 320# output: report(0x00000002);\n 321# output: report(0xfffffffd);\n 322# output: report(0xfffffffa);\n 323# output: report(0x00000001);\n 324# output: report(0x00000000);\n 325# output: report(0x00000001);\n 326# output: \n 327# output: report(0xffff7fff);\n 328# output: report(0xffff0000);\n 329# output: report(0x80010000);\n 330# output: report(0x00000001);\n 331# output: report(0x00000000);\n 332# output: report(0x00000001);\n 333# output: \n 334# output: exit(0)\n 335 336#include "or1k-asm-test-helpers.h" 337 338 STANDARD_TEST_ENVIRONMENT 339 340 .section .exception_vectors 341 342 /* Range exception. */ 343 .org 0xb00 344 345 /* The handling is a bit dubious at present. We just patch the 346 instruction with l.nop and restart. This will go wrong in branch 347 delay slots, but we are not testing that here. */ 348 l.addi r1, r1, -EXCEPTION_STACK_SKIP_SIZE 349 PUSH r2 350 PUSH r3 351 /* Save the address of the instruction that caused the problem. */ 352 MOVE_FROM_SPR r2, SPR_EPCR_BASE 353 LOAD_IMMEDIATE r3, 0x15000000 /* Opcode for l.nop */ 354 l.sw 0(r2), r3 355 POP r3 356 POP r2 357 l.addi r1, r1, EXCEPTION_STACK_SKIP_SIZE 358 l.rfe 359 360 .section .text 361start_tests: 362 PUSH LINK_REGISTER_R9 363 364 /* Test l.mul */ 365 366 /* Multiply two small positive numbers. This should set no flags. 367 */ 368 TEST_INST_I32_I32 l.mul, 0x00000002, 0x00000003 369 370 /* Multiply two quite large positive numbers. This should set no 371 flags */ 372 TEST_INST_I32_I32 l.mul, 0x00008001, 0x0000fffe 373 374 /* Multiply two slightly too large positive numbers. This should 375 set the overflow, but not the carry flag . */ 376 TEST_INST_I32_I32 l.mul, 0x00008000, 0x00010000 377 378 /* Multiply two large positive numbers. This should set the 379 overflow flags (even though the result is not a negative 380 number. */ 381 TEST_INST_I32_I32 l.mul, 0x00010000, 0x00010000 382 383 /* Multiply two small negative numbers. This will set no flags. */ 384 TEST_INST_I32_I32 l.mul, 0xfffffffe, 0xfffffffd 385 386 /* Multiply two quite large negative numbers. This will no flags. */ 387 TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0002 388 389 /* Multiply two slightly too large negative numbers. This should 390 set the overflow flag. */ 391 TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0000 392 393 /* Multiply two large negative numbers. This should set the 394 both the carry and overflow flags (even though the result is a 395 positive number. */ 396 TEST_INST_I32_I32 l.mul, 0xffff0000, 0xfffeffff 397 398 /* Multiply one small negative number and one small positive 399 number. This will set the no flags. */ 400 TEST_INST_I32_I32 l.mul, 0x00000002, 0xfffffffd 401 402 /* Multiply one quite large negative number and one quite large 403 positive number. This will set no flags. */ 404 TEST_INST_I32_I32 l.mul, 0xffff8000, 0x00010000 405 406 /* Multiply one slightly too large negative number and one slightly 407 too large positive number. This should set the overflow flag. */ 408 TEST_INST_I32_I32 l.mul, 0xffff7fff, 0x00010000 409 410 /* Multiply the largest negative number by positive unity. This 411 should set neither carry, nor overflow flag. */ 412 TEST_INST_I32_I32 l.mul, 0x80000000, 0x00000001 413 414 /* Check that range exceptions are triggered. */ 415 416 SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3 417 418 /* Check that an overflow alone causes a RANGE Exception. */ 419 TEST_INST_I32_I32 l.mul, 0x00008000, 0x00010000 420 421 /* Check multiply of a negative and positive does not cause a RANGE 422 Exception. */ 423 TEST_INST_I32_I32 l.mul, 0x00000002, 0xfffffffd 424 425 /* Check that negative overflow causes a RANGE exception. */ 426 TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0000 427 428 CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3 429 430 431 /* Test l.muli */ 432 433 /* Multiply two small positive numbers. This should set no flags. */ 434 TEST_INST_I32_I16 l.muli, 0x00000002, 0x0003 435 436 /* Multiply two quite large positive numbers. This should set no 437 flags */ 438 TEST_INST_I32_I16 l.muli, 0x00010002, 0x7fff 439 440 /* Multiply two slightly too large positive numbers. This should 441 set the overflow, but not the carry flag. */ 442 TEST_INST_I32_I16 l.muli, 0x00020000, 0x4000 443 444 /* Multiply two large positive numbers. This should set the 445 overflow flag, even though the result is not a negative number. */ 446 TEST_INST_I32_I16 l.muli, 0x00040000, 0x4000 447 448 /* Multiply two small negative numbers. This should set no flags. */ 449 TEST_INST_I32_I16 l.muli, 0xfffffffe, 0xfffd 450 451 /* Multiply two quite large negative numbers. This will set no 452 flags. */ 453 TEST_INST_I32_I16 l.muli, 0xfffefffe, 0x8001 454 455 /* Multiply two slightly too large negative numbers. This should 456 set the overflow flag. */ 457 TEST_INST_I32_I16 l.muli, 0xfffe0000, 0xbfff 458 459 /* Multiply two large negative numbers. This should set the 460 overflow flag, even though the result is a positive number. */ 461 TEST_INST_I32_I16 l.muli, 0xfffdfffe, 0x8000 462 463 /* Multiply one small negative number and one small positive 464 number. This will set no flags. */ 465 TEST_INST_I32_I16 l.muli, 0x00000002, 0xfffd 466 467 /* Multiply one quite large negative number and one quite large 468 positive number. This will set no flags. */ 469 TEST_INST_I32_I16 l.muli, 0x00010000, 0x8000 470 471 /* Multiply one slightly too large negative number and one slightly 472 too large positive number. This will set the overflow flag. */ 473 TEST_INST_I32_I16 l.muli, 0xfffdfffc, 0x4000 474 475 /* Multiply the largest negative number by positive unity. Should 476 set neither carry, nor overflow flag. */ 477 TEST_INST_I32_I16 l.muli, 0x80000000, 0x0001 478 479 /* Check that range exceptions are triggered. */ 480 481 SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3 482 483 /* Check that an overflow alone causes a RANGE Exception. */ 484 TEST_INST_I32_I16 l.muli, 0x00020000, 0x4000 485 486 /* Check that two negatives will not cause a RANGE Exception. */ 487 TEST_INST_I32_I16 l.muli, 0xfffffffe, 0xfffd 488 489 /* Check that multiply of larget negative and positive numbers causes 490 a RANGE exception and overflow. */ 491 TEST_INST_I32_I16 l.muli, 0xfffdfffe, 0x8000 492 493 CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3 494 495 /* Test l.mulu */ 496 497 /* Multiply two small positive numbers. This should set no flags. */ 498 TEST_INST_I32_I32 l.mulu, 0x00000002, 0x00000003 499 500 /* Multiply two quite large positive numbers. This should set no 501 flags. */ 502 TEST_INST_I32_I32 l.mulu, 0x00008001, 0x0000fffe 503 504 /* Multiply two slightly too large positive numbers. This will set 505 no flags. */ 506 TEST_INST_I32_I32 l.mulu, 0x00008000, 0x00010000 507 508 /* Multiply two large positive numbers. This will set the overflow 509 flag. */ 510 TEST_INST_I32_I32 l.mulu, 0x00010000, 0x00010000 511 512 /* Multiply two small negative numbers. This will set the 513 carry flag, but not the overflow flag. */ 514 TEST_INST_I32_I32 l.mulu, 0xfffffffe, 0xfffffffd 515 516 /* Multiply two quite large negative numbers. This will set the 517 carry flag, but not the overflow flag. */ 518 TEST_INST_I32_I32 l.mulu, 0xffff7fff, 0xffff0002 519 520 /* Multiply two slightly too large negative numbers. This will set 521 the carry flag, and not the overflow flag */ 522 TEST_INST_I32_I32 l.mulu, 0xffff7fff, 0xffff0000 523 524 /* Multiply two large negative numbers. This will set the both the 525 carry flag (even though the result is a positive number.) */ 526 TEST_INST_I32_I32 l.mulu, 0xffff0000, 0xfffeffff 527 528 /* Multiply one small negative number and one small positive 529 number. This will set the carry flag, but not the overflow 530 flag. */ 531 TEST_INST_I32_I32 l.mulu, 0x00000002, 0xfffffffd 532 533 /* Multiply one quite large negative number and one quite large 534 positive number. This will set the carry flag, but not the 535 overflow flag. */ 536 TEST_INST_I32_I32 l.mulu, 0xffff8000, 0x00010000 537 538 /* Multiply one slightly too large negative number and one slightly 539 too large positive number. This will set the carry flag, but 540 not the overflow flag. */ 541 TEST_INST_I32_I32 l.mulu, 0xffff7fff, 0x00010000 542 543 /* Multiply the largest negative number by positive unity. Should 544 set neither carry, nor overflow flag. */ 545 TEST_INST_I32_I32 l.mulu, 0x80000000, 0x00000001 546 547 /* Check that range exceptions are never triggered. */ 548 549 SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3 550 551 /* Check that what would cause an overflow alone in 2's complement 552 does not cause a RANGE Exception. */ 553 TEST_INST_I32_I32 l.mulu, 0x00008000, 0x00010000 554 555 /* Check that a carry causes a RANGE Exception. */ 556 TEST_INST_I32_I32 l.mulu, 0x00000002, 0xfffffffd 557 558 /* Check that what would cause an overflow and carry in 2's 559 complement causes a RANGE Exception. */ 560 TEST_INST_I32_I32 l.mulu, 0xffff7fff, 0xffff0000 561 562 CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3 563 564 POP LINK_REGISTER_R9 565 RETURN_TO_LINK_REGISTER_R9 566