mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-03-05 16:09:49 +00:00
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 <vapier@gentoo.org>
This commit is contained in:
parent
6aafca16ed
commit
5f2804c950
@ -1,3 +1,9 @@
|
||||
2012-03-19 Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
* 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 <stuart.henderson@analog.com>
|
||||
|
||||
* c_dsp32shiftim_amix.s: Check edge cases in shift behavior.
|
||||
|
@ -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;
|
||||
.macro se_all_new_insn_stub
|
||||
jump _legal_instruction;
|
||||
.endm
|
||||
.macro se_all_new_insn_log
|
||||
se_all_new_16bit_insn_log
|
||||
.endm
|
||||
|
||||
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;
|
||||
|
||||
.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
|
||||
|
@ -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;
|
||||
.macro se_all_new_insn_stub
|
||||
jump fail_lvl;
|
||||
.endm
|
||||
.macro se_all_new_insn_log
|
||||
se_all_new_32bit_insn_log
|
||||
.endm
|
||||
|
||||
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;
|
||||
|
||||
.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
|
||||
|
211
sim/testsuite/sim/bfin/se_allopcodes.h
Normal file
211
sim/testsuite/sim/bfin/se_allopcodes.h
Normal file
@ -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: <nothing>
|
||||
* 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
|
Loading…
x
Reference in New Issue
Block a user