40bit_test.ds 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. ; This test covers the behavior of 40-bit mode for a variety of values.
  2. ; It takes a while to run completely (~5 minutes), but progress is indicated via mail shown at the
  3. ; top of the screen in DSPSpy. The value will go from 80000000 to 8041ffff.
  4. incdir "tests"
  5. include "dsp_base.inc"
  6. test_main:
  7. LRI $ar0, #0
  8. LRI $ar1, #0
  9. LRI $ar2, #0
  10. LRI $ar3, #0
  11. LRI $ix0, #0
  12. LRI $ix1, #0
  13. LRI $ix2, #0
  14. LRI $ix3, #0
  15. ; Test with $ac0.l from 0xfff0 to 0x0010
  16. LRI $ac0.l, #0xfff0
  17. BLOOPI #0x21, first_loop_last_ins
  18. CALL test_saturation
  19. IAR $ar0
  20. first_loop_last_ins:
  21. INC $acc0
  22. ; Test with $ac0.l from 0x7ff0 to 0x8010
  23. LRI $ac0.l, #0xfff0
  24. BLOOPI #0x21, second_loop_last_ins
  25. CALL test_saturation
  26. IAR $ar0
  27. second_loop_last_ins:
  28. INC $acc0
  29. ; We're done. Report the test results.
  30. ; $ix1 should be 0, or else saturation occurred on $ac0.l or $ac0.h.
  31. ; $ix2 should be 0, or else sign-extension occurred on $ac0.l or $ac0.h.
  32. ; $ix3 should be 0, or else we incorrectly predicted saturation on $ac0.m.
  33. ; $ar1/$ar2/$ar3 records the number of times it happened
  34. CALL send_back
  35. ; We're done, DO NOT DELETE THIS LINE
  36. JMP end_of_test
  37. test_saturation:
  38. ; We start with $ac0.h at -0x80 since we can use the overflow flag to check when wrapping around
  39. ; occurs; starting at 0 and ending when it wraps back to 0 doesn't work since we can't check the
  40. ; zero flag since $ac0.l may be nonzero ($ac0.l is used as an input to this subroutine)
  41. LRI $ac0.m, #0
  42. LRI $ac0.h, #-0x80
  43. loop_start:
  44. ; Compare the value of $ac0.m when in SET16 mode and in SET40 mode
  45. SET40
  46. ; Reading $ac0.m in SET40 mode results in saturation if $ac0.h doesn't match the sign-extension
  47. ; of $ac0.h. Also, storing to $ac1.m in SET40 mode clears $ac1.l and sets $ac1.h to the
  48. ; sign-extension of $ac1.m, and $ac1.l.
  49. MRR $ac1.m, $ac0.m
  50. SET16
  51. ; Attempt to compute the saturated value of $ac1.m in $ax1.h,
  52. ; using what we know of $acc0.
  53. TST'MV $acc0 : $ax1.h, $ac0.m
  54. JL negative_acc0
  55. ; $acc0 is nonnegative.
  56. JMPx8 check_saturated_ax1h ; If the above s32 bit is not set, we don't need to saturate
  57. ; If the above s32 bit _is_ set, then saturate $ax1.h.
  58. LRI $ax1.h, #0x7fff
  59. JMP check_saturated_ax1h
  60. negative_acc0:
  61. JMPx8 check_saturated_ax1h ; If the above s32 bit is not set, we don't need to saturate
  62. LRI $ax1.h, #0x8000
  63. ; Fall through to check_saturated_ax1h
  64. check_saturated_ax1h:
  65. ; $acc1 has the value of $ac0.m in SET40 mode.
  66. ; And, $ax1.h has what we computed that value should be, and CMPAXH always sign-extends $ax1.h
  67. ; (and ignores $ax1.l), so we can compare using it directly.
  68. CMPAXH $acc1, $ax1.h
  69. JZ check_read_low
  70. ; Our prediction was wrong (shouldn't happen)
  71. LRI $ix3, #1
  72. IAR $ar3
  73. TST $acc0
  74. CALL send_back
  75. ; Fall through to check_read_low
  76. check_read_low:
  77. SET40
  78. MRR $ac1.m, $ac0.l
  79. SET16
  80. MRR $ax1.h, $ac0.l
  81. CMPAXH $acc1, $ax1.h
  82. JZ check_read_high
  83. ; Reading $ac0.l gave different results in SET40 and SET16 modes (shouldn't happen)
  84. LRI $ix1, #1
  85. IAR $ar1
  86. TST $acc0
  87. CALL send_back
  88. ; Fall through to check_read_high
  89. check_read_high:
  90. SET40
  91. MRR $ac1.m, $ac0.h
  92. SET16
  93. MRR $ax1.h, $ac0.h
  94. CMPAXH $acc1, $ax1.h
  95. JZ check_write_low
  96. ; Reading $ac0.h gave different results in SET40 and SET16 modes (shouldn't happen)
  97. LRI $ix1, #1
  98. IAR $ar1
  99. TST $acc0
  100. CALL send_back
  101. ; Fall through to check_write_low
  102. check_write_low:
  103. MOV $acc1, $acc0
  104. SET40
  105. MRR $ac1.l, $ac0.l
  106. SET16
  107. CMP
  108. JZ check_write_high
  109. ; Writing to $ac1.l caused $acc1 to not match $acc0 (shouldn't happen)
  110. LRI $ix2, #1
  111. IAR $ar2
  112. CALL send_back
  113. ; Fall through to check_write_high
  114. check_write_high:
  115. MOV $acc1, $acc0
  116. SET40
  117. MRR $ac1.h, $ac0.h
  118. SET16
  119. CMP
  120. JZ increment_loop
  121. ; Writing to $ac1.h caused $acc1 to not match $acc0 (shouldn't happen)
  122. LRI $ix2, #1
  123. IAR $ar2
  124. CALL send_back
  125. ; Fall through to increment_loop
  126. increment_loop:
  127. INCM $ac0.m
  128. ; If incrementing results in overflowing, then we're done.
  129. RETO
  130. ; If ($ac0.m & 0x00ff) != 0, continue the loop without sending mail.
  131. ANDF $ac0.m, #0x00ff
  132. JLNZ loop_start
  133. ; Otherwise, send mail to report the progress. (This shows at the top of the screen in DSPSpy,
  134. ; but otherwise isn't handled in any meaningful way.)
  135. MOV $acc1, $acc0
  136. LSR $acc1, #-8
  137. ; Compensate for starting at INT_MIN (0x80'0000'0000) and ending at INT_MAX (0x7f'0000'0000)
  138. ; instead of going from 0 (0x00'0000'0000) to -1 (0xff'ffff'ffff)
  139. XORI $ac1.m, #0x8000
  140. SR @DMBH, $ar0
  141. SR @DMBL, $ac1.m
  142. SI @DIRQ, #0x0001
  143. ; We don't wait for the mail to be read, because we don't care about the response.
  144. JMP loop_start