From 5f2804c950de124687ebdf60300e857d3586e383 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 19 Mar 2012 05:34:30 +0000 Subject: [PATCH] sim: bfin: unify se_all*opcodes tests The current se_all*opcodes tests are very similar in how they work. In preparation for adding more tests along these lines, unify the common bits into a framework that others can include and build off of easily. Signed-off-by: Mike Frysinger --- sim/testsuite/sim/bfin/ChangeLog | 6 + sim/testsuite/sim/bfin/se_all16bitopcodes.S | 162 ++------------- sim/testsuite/sim/bfin/se_all32bitopcodes.S | 163 ++------------- sim/testsuite/sim/bfin/se_allopcodes.h | 211 ++++++++++++++++++++ 4 files changed, 255 insertions(+), 287 deletions(-) create mode 100644 sim/testsuite/sim/bfin/se_allopcodes.h diff --git a/sim/testsuite/sim/bfin/ChangeLog b/sim/testsuite/sim/bfin/ChangeLog index 828ad62145..23b6cd2648 100644 --- a/sim/testsuite/sim/bfin/ChangeLog +++ b/sim/testsuite/sim/bfin/ChangeLog @@ -1,3 +1,9 @@ +2012-03-19 Mike Frysinger + + * se_allopcodes.h: New framework for testing opcode regions. + * se_all16bitopcodes.S: Convert over to se_allopcodes.h. + * se_all32bitopcodes.S: Likewise. + 2012-03-19 Stuart Henderson * c_dsp32shiftim_amix.s: Check edge cases in shift behavior. diff --git a/sim/testsuite/sim/bfin/se_all16bitopcodes.S b/sim/testsuite/sim/bfin/se_all16bitopcodes.S index 12894f0b90..6a6d76c27e 100644 --- a/sim/testsuite/sim/bfin/se_all16bitopcodes.S +++ b/sim/testsuite/sim/bfin/se_all16bitopcodes.S @@ -12,122 +12,20 @@ # sim: --environment operating #include "test.h" +#include "se_allopcodes.h" .include "testutils.inc" - start - - /* Set up exception handler */ - imm32 P4, EVT3; - loadsym R1, _evx; - [P4] = R1; - - /* set up the _location */ - loadsym P0, _location - loadsym P1, _table; - [P0] = P1; - - /* Enable single stepping */ - R0 = 1; - SYSCFG = R0; - - /* Lower to the code we want to single step through */ - loadsym P1, _usr; - RETI = P1; - - /* set up pointers to valid data (32Meg), to reduce address violations */ - .macro reset_regs - imm32 r0, 0x2000000; - l0 = 0; l1 = 0; l2 = 0; l3 = 0; - p0 = r0; p1 = r0; p2 = r0; p3 = r0; p4 = r0; p5 = r0; - usp = r0; fp = r0; - i0 = r0; i1 = r0; i2 = r0; i3 = r0; - b0 = r0; b1 = r0; b2 = r0; b3 = r0; - .endm - reset_regs - - RTI; - - .align 4; -_evx: - /* Make sure exception reason is single step */ - R3 = SEQSTAT; - R4 = 0x3f; - R3 = R3 & R4; - - /* find a match */ - loadsym P5, _usr; - loadsym P4, _location; +.macro se_all_load_insn R2 = W[P5]; - P1 = [P4]; R0 = R2; - -_match: - P2 = P1; +.endm +.macro se_all_load_table R7 = W[P1++]; R6 = W[P1++]; R5 = W[P1++]; +.endm - /* is this the end of the table? */ - R4 = 0; - CC = R4 == R7; - IF CC jump _new_instruction; - - /* is the opcode (R0) greater than the 2nd entry in the table (R6) */ - /* if so look at the next line in the table */ - CC = R6 < R0; - if CC jump _match; - - /* is the opcode (R0) smaller than the first entry in the table (R7) */ - /* this means it's somewhere between the two lines, and should be legal */ - CC = R7 <= R0; - if !CC jump _legal_instruction; - - /* is the current EXCAUSE (R3), the same as the table (R5) */ - /* if not, fail */ - CC = R3 == R5 - if !CC jump fail_lvl; - -_match_done: - /* back up, and store the location to search next */ - [P4] = P2; - - /* it matches, so fall through */ - jump _next_instruction; - -_new_instruction: - jump _legal_instruction; - - /* output the insn (R0) and excause (R3) if diff from last */ - loadsym P0, _last_excause; - R2 = [P0]; - CC = R2 == R3; - IF CC jump _next_instruction; - [P0] = R3; - -.ifdef BFIN_JTAG_xxxxx - R1 = R0; - R0 = 0x4; - call __emu_out; - R0 = R1 << 16; - R0 = R0 | R3; - call __emu_out; -.else - loadsym P0, _next_location; - P1 = [P0]; - W[P1++] = R0; - W[P1++] = R3; - [P0] = P1; -.endif - - jump _next_instruction; - -_legal_instruction: - R4 = 0x10; - CC = R3 == R4; - IF !CC JUMP fail_lvl; - /* it wasn't in the list, and was a single step, so fall through */ - -_next_instruction: +.macro se_all_next_insn /* increment, and go again. */ R0 = R2; @@ -138,44 +36,20 @@ _next_instruction: IF CC JUMP pass_lvl; W[P5] = R0; +.endm - /* Make sure the opcode isn't in a write buffer */ - SSYNC; - - R1 = P5; - RETX = R1; - - /* set up pointers to valid data (32Meg), to reduce address violations */ - reset_regs - RETS = r0; - RETN = r0; - RETE = r0; - RETI = r0; - - RTX; - -pass_lvl: - dbg_pass; -fail_lvl: - dbg_fail; +.macro se_all_new_insn_stub + jump _legal_instruction; +.endm +.macro se_all_new_insn_log + se_all_new_16bit_insn_log +.endm - .section .text.usr - .align 4 -_usr: +.macro se_all_insn_init .dw 0x0000; - loadsym P0, fail_lvl; - JUMP (P0); - +.endm +.macro se_all_insn_table /* this table must be sorted, and end with zero */ - .data - .align 4; -_last_excause: - .dd 0xffff -_next_location: - .dd _table_end -_location: - .dd 0 -_table: /* start end SEQSTAT */ .dw 0x0001, 0x000f, 0x21 .dw 0x0011, 0x0013, 0x2e @@ -475,4 +349,6 @@ _table: .dw 0x9ef0, 0x9eff, 0x21 .dw 0x9f70, 0x9f7f, 0x21 .dw 0x0000, 0x0000, 0x00 -_table_end: +.endm + + se_all_test diff --git a/sim/testsuite/sim/bfin/se_all32bitopcodes.S b/sim/testsuite/sim/bfin/se_all32bitopcodes.S index be3b395975..90b1ff6b4c 100644 --- a/sim/testsuite/sim/bfin/se_all32bitopcodes.S +++ b/sim/testsuite/sim/bfin/se_all32bitopcodes.S @@ -14,125 +14,22 @@ # xfail: too many invalid insns are decoded as valid #include "test.h" +#include "se_allopcodes.h" .include "testutils.inc" - start - - /* Set up exception handler */ - imm32 P4, EVT3; - loadsym R1, _evx; - [P4] = R1; - - /* set up the _location */ - loadsym P0, _location - loadsym P1, _table; - [P0] = P1; - - /* Enable single stepping */ - R0 = 1; - SYSCFG = R0; - - /* Lower to the code we want to single step through */ - loadsym P1, _usr; - RETI = P1; - - /* set up pointers to valid data (32Meg), to reduce address violations */ - .macro reset_regs - imm32 r0, 0x2000000; - l0 = 0; l1 = 0; l2 = 0; l3 = 0; - p0 = r0; p1 = r0; p2 = r0; p3 = r0; p4 = r0; p5 = r0; - usp = r0; fp = r0; - i0 = r0; i1 = r0; i2 = r0; i3 = r0; - b0 = r0; b1 = r0; b2 = r0; b3 = r0; - .endm - reset_regs - - RTI; - - .align 4; -_evx: - /* Make sure exception reason is single step */ - R3 = SEQSTAT; - R4 = 0x3f; - R3 = R3 & R4; - - /* find a match */ - loadsym P5, _usr; - loadsym P4, _location; +.macro se_all_load_insn R2 = [P5]; - P1 = [P4]; R0 = R2 << 16; R1 = R2 >> 16; R0 = R0 | R1; - -_match: - P2 = P1; +.endm +.macro se_all_load_table R7 = [P1++]; R6 = [P1++]; R5 = [P1++]; +.endm - /* is this the end of the table? */ - R4 = 0; - CC = R4 == R7; - IF CC jump _new_instruction; - - /* is the opcode (R0) greater than the 2nd entry in the table (R6) */ - /* if so look at the next line in the table */ - CC = R6 < R0; - if CC jump _match; - - /* is the opcode (R0) smaller than the first entry in the table (R7) */ - /* this means it's somewhere between the two lines, and should be legal */ - CC = R7 <= R0; - if !CC jump _legal_instruction; - - /* is the current EXCAUSE (R3), the same as the table (R5) */ - /* if not, fail */ - CC = R3 == R5 - if !CC jump fail_lvl; - -_match_done: - /* back up, and store the location to search next */ - [P4] = P2; - - /* it matches, so fall through */ - jump _next_instruction; - -_new_instruction: - jump fail_lvl; - - /* output the insn (R0) and excause (R3) if diff from last */ - loadsym P0, _last_excause; - R2 = [P0]; - CC = R2 == R3; - IF CC jump _next_instruction; - [P0] = R3; - -.ifdef BFIN_JTAG_xxxxx - R1 = R0; - R0 = 0x8; - call __emu_out; - R0 = R1; - call __emu_out; - R0 = R3; - call __emu_out; -.else - loadsym P0, _next_location; - P1 = [P0]; - [P1++] = R0; - [P1++] = R3; - [P0] = P1; -.endif - - jump _next_instruction; - -_legal_instruction: - R4 = 0x10; - CC = R3 == R4; - IF !CC JUMP fail_lvl; - /* it wasn't in the list, and was a single step, so fall through */ - -_next_instruction: +.macro se_all_next_insn /* increment, and go again. */ R0 = R2; @@ -169,45 +66,21 @@ _next_instruction: 1: [P5] = R0; +.endm - /* Make sure the opcode isn't in a write buffer */ - SSYNC; - - R1 = P5; - RETX = R1; - - /* set up pointers to valid data (32Meg), to reduce address violations */ - reset_regs - RETS = r0; - RETN = r0; - RETE = r0; - RETI = r0; - - RTX; - -pass_lvl: - dbg_pass; -fail_lvl: - dbg_fail; +.macro se_all_new_insn_stub + jump fail_lvl; +.endm +.macro se_all_new_insn_log + se_all_new_32bit_insn_log +.endm - .section .text.usr - .align 4 -_usr: +.macro se_all_insn_init .dw 0xc000; .dw 0x0000; - loadsym P0, fail_lvl; - JUMP (P0); - +.endm +.macro se_all_insn_table /* this table must be sorted, and end with zero */ - .data - .align 4; -_last_excause: - .dd 0xffff -_next_location: - .dd _table_end -_location: - .dd 0 -_table: /* start end SEQSTAT */ .dw 0x1a00, 0xc000, 0x1fff, 0xc000, 0x21, 0 .dw 0x3a00, 0xc000, 0x3fff, 0xc000, 0x21, 0 @@ -34301,4 +34174,6 @@ _table: .dw 0x0000, 0xe740, 0xffff, 0xe7ff, 0x21, 0 .dw 0x0000, 0xf001, 0xffff, 0xffff, 0x21, 0 .dw 0x0000, 0x0000, 0x0000, 0x0000, 0x00, 0 -_table_end: +.endm + + se_all_test diff --git a/sim/testsuite/sim/bfin/se_allopcodes.h b/sim/testsuite/sim/bfin/se_allopcodes.h new file mode 100644 index 0000000000..2e4567373d --- /dev/null +++ b/sim/testsuite/sim/bfin/se_allopcodes.h @@ -0,0 +1,211 @@ +/* + * set up pointers to valid data (32Meg), to reduce address violations + */ +.macro reset_dags + imm32 r0, 0x2000000; + l0 = 0; l1 = 0; l2 = 0; l3 = 0; + p0 = r0; p1 = r0; p2 = r0; p3 = r0; p4 = r0; p5 = r0; + usp = r0; fp = r0; + i0 = r0; i1 = r0; i2 = r0; i3 = r0; + b0 = r0; b1 = r0; b2 = r0; b3 = r0; +.endm + +/* + * execute a test of an opcode space. host test + * has to fill out a number of callbacks. + * + * se_all_insn_init + * the first insn to start executing + * se_all_insn_table + * the table of insn ranges and expected seqstat + * + * se_all_load_insn + * in: P5 + * out: R0, R2 + * scratch: R1 + * load current user insn via register P5 into R0. + * register R2 is available for caching with se_all_next_insn. + * se_all_load_table + * in: P1 + * out: R7, R6, R5 + * scratch: R1 + * load insn range/seqstat entry from table via register P1 + * R7: low range + * R6: high range + * R5: seqstat + * + * se_all_next_insn + * in: P5, R2 + * out: + * scratch: all but P5 + * advance current insn to next one for testing. register R2 + * is retained from se_all_load_insn. write out new insn to + * the location via register P5. + * + * se_all_new_insn_stub + * se_all_new_insn_log + * for handling of new insns ... generally not needed once done + */ +.macro se_all_test + start + + /* Set up exception handler */ + imm32 P4, EVT3; + loadsym R1, _evx; + [P4] = R1; + + /* set up the _location */ + loadsym P0, _location + loadsym P1, _table; + [P0] = P1; + + /* Enable single stepping */ + R0 = 1; + SYSCFG = R0; + + /* Lower to the code we want to single step through */ + loadsym P1, _usr; + RETI = P1; + + /* set up pointers to valid data (32Meg), to reduce address violations */ + reset_dags + + RTI; + +pass_lvl: + dbg_pass; +fail_lvl: + dbg_fail; + +_evx: + /* Make sure exception reason is as we expect */ + R3 = SEQSTAT; + R4 = 0x3f; + R3 = R3 & R4; + + /* find a match */ + loadsym P5, _usr; + loadsym P4, _location; + P1 = [P4]; + se_all_load_insn + +_match: + P2 = P1; + se_all_load_table + + /* is this the end of the table? */ + R4 = 0; + CC = R4 == R7; + IF CC jump _new_instruction; + + /* is the opcode (R0) greater than the 2nd entry in the table (R6) */ + /* if so look at the next line in the table */ + CC = R6 < R0; + if CC jump _match; + + /* is the opcode (R0) smaller than the first entry in the table (R7) */ + /* this means it's somewhere between the two lines, and should be legal */ + CC = R7 <= R0; + if !CC jump _legal_instruction; + + /* is the current EXCAUSE (R3), the same as the table (R5) */ + /* if not, fail */ + CC = R3 == R5 + if !CC jump fail_lvl; + +_match_done: + /* back up, and store the location to search next */ + [P4] = P2; + + /* it matches, so fall through */ + jump _next_instruction; + +_new_instruction: + se_all_new_insn_stub + + /* output the insn (R0) and excause (R3) if diff from last */ + loadsym P0, _last_excause; + R2 = [P0]; + CC = R2 == R3; + IF CC jump _next_instruction; + [P0] = R3; + + se_all_new_insn_log + +_legal_instruction: + R4 = 0x10; + CC = R3 == R4; + IF !CC JUMP fail_lvl; + /* it wasn't in the list, and was a single step, so fall through */ + +_next_instruction: + se_all_next_insn + + /* Make sure the opcode isn't in a write buffer */ + SSYNC; + + R1 = P5; + RETX = R1; + + /* set up pointers to valid data (32Meg), to reduce address violations */ + reset_dags + RETS = r0; + RETN = r0; + RETE = r0; + RETI = r0; + + RTX; + +.section .text.usr + .align 4 +_usr: + se_all_insn_init + loadsym P0, fail_lvl; + JUMP (P0); + +.data + .align 4; +_last_excause: + .dd 0xffff +_next_location: + .dd _table_end +_location: + .dd 0 +_table: + se_all_insn_table +_table_end: +.endm + +.macro se_all_new_16bit_insn_log +.ifdef BFIN_JTAG_xxxxx + R1 = R0; + R0 = 0x4; + call __emu_out; + R0 = R1 << 16; + R0 = R0 | R3; + call __emu_out; +.else + loadsym P0, _next_location; + P1 = [P0]; + W[P1++] = R0; + W[P1++] = R3; + [P0] = P1; +.endif +.endm +.macro se_all_new_32bit_insn_log +.ifdef BFIN_JTAG_xxxxx + R1 = R0; + R0 = 0x8; + call __emu_out; + R0 = R1; + call __emu_out; + R0 = R3; + call __emu_out; +.else + loadsym P0, _next_location; + P1 = [P0]; + [P1++] = R0; + [P1++] = R3; + [P0] = P1; +.endif +.endm -- 2.34.1