incdir "tests" include "dsp_base.inc" input_ax: ; [0] - 0x0000'0000 - 0 CW 0 CW 0 ; [1] - 0x0000'0001 - 1 in $ax0.l CW 0 CW 1 ; [2] - 0x0000'ffff - -1 in $ax0.l CW 0 CW 0xffff ; [3] - 0x0001'0000 - 1 in $ax0.h CW 1 CW 0 ; [4] - 0x7fff'0000 - INT_MAX in $ax0.h CW 0x7fff CW 0 ; [5] - 0x8000'0000 - INT_MIN in $ax0.h CW 0x8000 CW 0 ; [6] - 0xffff'0000 - -1 in $ax0.h CW 0xffff CW 0 input_ax_end: input_acc: ; [0] - 0x00'0000'0000 - 0 CW 0 CW 0 CW 0 ; [1] - 0x00'0000'0001 - 1 in $ac0.l CW 0 CW 0 CW 1 ; [2] - 0x00'0000'ffff - -1 in $ac0.l CW 0 CW 0 CW 1 ; [3] - 0x00'0001'0000 - 1 in $ac0.m CW 0 CW 1 CW 0 ; [4] - 0x00'7fff'0000 - INT_MAX in $ac0.m CW 0 CW 0x7fff CW 0 ; [5] - 0x00'8000'0000 - INT_MIN in $ac0.m, but not sign extended CW 0 CW 0x8000 CW 0 ; [6] - 0x00'ffff'0000 - -1 in $ac0.m, but not sign extended CW 0 CW 0xffff CW 0 ; [7] - 0x01'0000'0000 - 1 in $ac0.l CW 1 CW 0 CW 0 ; [8] - 0x7f'ffff'0000 - true INT_MAX CW 0x7f CW 0xffff CW 0 ; [9] - 0x80'0000'0000 - true INT_MIN CW 0x80 CW 0 CW 0 ; [10] - 0xff'8000'0000 - INT_MIN in $ac0.m, sign-extended CW 0xff CW 0x8000 CW 0 ; [11] - 0xff'ffff'0000 - -1 CW 0xff CW 0xffff CW 0 input_acc_end: /* Python script to generate the following result tables from a DSP dump: import struct def gen_tables(name, num_ax, num_acc): with open(name, "rb") as fin: data = fin.read() reg_values = list(struct.iter_unpack(">" + "H"*0x20, data)) # Initial register values (there is no corresponding send_back call for these), then our two # default value checks, then the TSTAXH test, then the CMPAXH test, then the test results assert len(reg_values) == 1 + 2 + num_ax + num_ax * num_acc + 1 print("result_table_tstaxh:") for ax in range(num_ax): # SR is register 0x13 print("CW {:#04x}".format(reg_values[3 + ax][0x13])) print("result_table_tstaxh_end:") print() print("result_table_cmpaxh:") for ax in range(num_ax): print("; ax [{}]".format(ax)) for acc in range(num_acc): print("CW {:#04x}".format(reg_values[3 + num_ax + ax * num_acc + acc][0x13])) print("result_table_cmpaxh_end:") gen_tables("dsp_dump0.bin", 7, 12) */ result_table_tstaxh: CW 0x22a4 CW 0x22a4 CW 0x22a4 CW 0x22a0 CW 0x2280 CW 0x2288 CW 0x22a8 result_table_tstaxh_end: result_table_cmpaxh: ; ax [0] CW 0x22a5 CW 0x22a1 CW 0x22a1 CW 0x22a1 CW 0x2281 CW 0x2291 CW 0x22b1 CW 0x22b1 CW 0x22b1 CW 0x22b9 CW 0x2289 CW 0x22a9 ; ax [1] CW 0x22a5 CW 0x22a1 CW 0x22a1 CW 0x22a1 CW 0x2281 CW 0x2291 CW 0x22b1 CW 0x22b1 CW 0x22b1 CW 0x22b9 CW 0x2289 CW 0x22a9 ; ax [2] CW 0x22a5 CW 0x22a1 CW 0x22a1 CW 0x22a1 CW 0x2281 CW 0x2291 CW 0x22b1 CW 0x22b1 CW 0x22b1 CW 0x22b9 CW 0x2289 CW 0x22a9 ; ax [3] CW 0x22a8 CW 0x22a8 CW 0x22a8 CW 0x22a5 CW 0x2281 CW 0x2281 CW 0x22b1 CW 0x22b1 CW 0x22b1 CW 0x22b3 CW 0x2299 CW 0x22a9 ; ax [4] CW 0x2288 CW 0x2288 CW 0x2288 CW 0x2288 CW 0x22a5 CW 0x22a1 CW 0x2291 CW 0x2291 CW 0x2291 CW 0x2293 CW 0x22b9 CW 0x2289 ; ax [5] CW 0x2290 CW 0x2290 CW 0x2290 CW 0x2290 CW 0x22b0 CW 0x22b0 CW 0x2290 CW 0x2290 CW 0x229a CW 0x2298 CW 0x22a5 CW 0x2281 ; ax [6] CW 0x22a0 CW 0x22a0 CW 0x22a0 CW 0x22a0 CW 0x2290 CW 0x2290 CW 0x22b0 CW 0x22b0 CW 0x22ba CW 0x22b8 CW 0x2288 CW 0x22a5 result_table_cmpaxh_end: test_main: ; Perform one test using the default values ; ($acc0 is 14 0009 0007 and $ax0 is 8000 0003, but this can be changed in the DSPSpy UI) ; Also, as a sanity check, record the computed sizes of the result tables LRI $ar0, #input_ax LRI $ix0, #(input_ax_end - input_ax) LRI $ar1, #input_acc LRI $ix1, #(input_acc_end - input_acc) LRI $ar2, #result_table_tstaxh LRI $ix2, #(input_ax_end - input_ax)/2 LRI $ar3, #result_table_cmpaxh LRI $ix3, #((input_ax_end - input_ax)/2)*((input_acc_end - input_acc)/3) ; Set the sticky overflow bit just so that we get consistent $sr values ; before and after an overflow occurs SBSET #1 CMPAXH $acc0, $ax0.h CALL send_back ; Expected $sr: 2290 ; $ar0 should match $ix0, etc ADDARN $ar0, $ix0 LRI $ix0, #input_ax_end ADDARN $ar1, $ix1 LRI $ix1, #input_acc_end ADDARN $ar2, $ix2 LRI $ix2, #result_table_tstaxh_end ADDARN $ar3, $ix3 LRI $ix3, #result_table_cmpaxh_end TSTAXH $ax0.h CALL send_back ; Expected $sr: 2288 CLR $acc0 CLR $acc1 LRI $ax0.h, #0 LRI $ax0.l, #0 LRI $ax1.h, #0 LRI $ax1.l, #0 ; Check TSTAXH... LRI $ar0, #input_ax LRI $ar2, #result_table_tstaxh ; for (int ctr = input_ax.size(); ctr > 0; ctr--) { BLOOPI #(input_ax_end - input_ax)/2, check_tstaxh_last_ins ; Note: if DSPSpy supported populating DMEM as well as IMEM, then there are several ; instructions that could make this faster and cleaner... but it doesn't currently, ; so we're stuck with ILRRI. ; Load the test value into $ax0.h/$ax0.l via $ac0.m ILRRI $ac0.m, $ar0 ; $ac0.m = IMEM[$ar0++] MRR $ax0.h, $ac0.m ILRRI $ac0.m, $ar0 MRR $ax0.l, $ac0.m ; Load the expected value into $ac1.m ILRRI $ac1.m, $ar2 ; $ac1.m = IMEM[$ar2++] ; Reduce noise in the results LRI $ac0.m, #0 ; Do the test TSTAXH $ax0.h CALL send_back ; Check if $sr matches the value we expected. If there is any difference, ; note it via a nonzero $ax1.l. (send_back saves the value of $sr) MRR $ac0.m, $sr CMP IFNZ LRIS $ax1.l, #1 check_tstaxh_last_ins: NOP ; } ; Check CMPAXH... CLR $acc0 CLR $acc1 LRI $ar0, #input_ax LRI $ar3, #result_table_cmpaxh ; for (int ctr_ax = input_ax.size(); ctr_ax > 0; ctr_ax--) { BLOOPI #(input_ax_end - input_ax)/2, check_cmpaxh_last_ins_outer ; Load the test value into $ax0.h/$ax0.l via $ac1.m ILRRI $ac1.m, $ar0 MRR $ax0.h, $ac1.m ILRRI $ac1.m, $ar0 MRR $ax0.l, $ac1.m LRI $ar1, #input_acc ; for (int ctr_acc = input_acc.size(); ctr_acc > 0; ctr_acc--) { BLOOPI #(input_acc_end - input_acc)/3, check_cmpaxh_last_ins_inner ; Load the test value into $ac0.h/$ac0.m/$ac0.l via $ac1.m ILRRI $ac1.m, $ar1 MRR $ac0.h, $ac1.m ILRRI $ac0.m, $ar1 ; we can load it directly here ILRRI $ac1.m, $ar1 MRR $ac0.l, $ac1.m ; Load the expected value into $ac1.m ILRRI $ac1.m, $ar3 ; Do the test CMPAXH $acc0, $ax0.h CALL send_back ; Check if $sr matches the value we expected. If there is any difference, ; note it via a nonzero $ax1.h. (send_back saves the value of $sr) ; We can overwrite $ac0.m here because we load it on the next iteration. MRR $ac0.m, $sr LRIS $ac0.l, #0 LRI $ac0.h, #0 CMP IFNZ LRIS $ax1.h, #1 check_cmpaxh_last_ins_inner: NOP ; } check_cmpaxh_last_ins_outer: NOP ; } ; We're done testing. In the final send_back call, if $ax1.l or $ax1.h ; is nonzero, the test failed. CALL send_back ; We're done, DO NOT DELETE THIS LINE JMP end_of_test