You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(43) |
Dec
(68) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(37) |
Feb
(41) |
Mar
(18) |
Apr
(60) |
May
(81) |
Jun
(7) |
Jul
(5) |
Aug
(2) |
Sep
(19) |
Oct
(36) |
Nov
(13) |
Dec
(35) |
2009 |
Jan
(9) |
Feb
(68) |
Mar
(37) |
Apr
(98) |
May
(139) |
Jun
(50) |
Jul
(14) |
Aug
(3) |
Sep
(2) |
Oct
(18) |
Nov
(13) |
Dec
(19) |
2010 |
Jan
(36) |
Feb
(87) |
Mar
(30) |
Apr
(8) |
May
(18) |
Jun
(103) |
Jul
(64) |
Aug
(97) |
Sep
(30) |
Oct
(33) |
Nov
(29) |
Dec
(29) |
2011 |
Jan
(36) |
Feb
(35) |
Mar
(54) |
Apr
(14) |
May
(30) |
Jun
(156) |
Jul
(133) |
Aug
(61) |
Sep
(16) |
Oct
(33) |
Nov
(17) |
Dec
(15) |
2012 |
Jan
(10) |
Feb
(25) |
Mar
(21) |
Apr
(12) |
May
(5) |
Jun
(4) |
Jul
(6) |
Aug
(30) |
Sep
(17) |
Oct
(19) |
Nov
(14) |
Dec
(7) |
2013 |
Jan
(10) |
Feb
(1) |
Mar
(14) |
Apr
(11) |
May
(9) |
Jun
(3) |
Jul
(1) |
Aug
|
Sep
|
Oct
(2) |
Nov
(3) |
Dec
(1) |
2014 |
Jan
(6) |
Feb
|
Mar
(1) |
Apr
(1) |
May
(9) |
Jun
(6) |
Jul
(1) |
Aug
(15) |
Sep
(1) |
Oct
(1) |
Nov
(5) |
Dec
(1) |
2015 |
Jan
(2) |
Feb
(4) |
Mar
(3) |
Apr
(1) |
May
(4) |
Jun
(2) |
Jul
|
Aug
(5) |
Sep
(3) |
Oct
|
Nov
|
Dec
(1) |
2016 |
Jan
|
Feb
|
Mar
(3) |
Apr
(5) |
May
|
Jun
(1) |
Jul
(3) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(7) |
2017 |
Jan
(6) |
Feb
(34) |
Mar
(59) |
Apr
|
May
(11) |
Jun
(11) |
Jul
(4) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
(8) |
Dec
(5) |
2018 |
Jan
|
Feb
(3) |
Mar
(42) |
Apr
|
May
|
Jun
(2) |
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(3) |
Jun
(10) |
Jul
(16) |
Aug
(56) |
Sep
(1) |
Oct
|
Nov
(2) |
Dec
(16) |
2020 |
Jan
(3) |
Feb
(6) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(5) |
Aug
|
Sep
(9) |
Oct
|
Nov
|
Dec
|
2021 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(2) |
Jul
|
Aug
|
Sep
(8) |
Oct
|
Nov
|
Dec
|
2022 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(6) |
Sep
(8) |
Oct
|
Nov
|
Dec
|
2023 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
From: Owen D. <ow...@ow...> - 2023-11-10 22:28:23
|
Hi, I offer the following tested patch to fix a defect in support of the "Olimex ARM-USB-TINY-H (FT2232H) Cable". Owen --- org/ft2232.c 2019-05-13 07:49:47.028616448 +1000 +++ ft2232.c 2023-11-11 07:34:56.614842343 +1100 @@ -2601,7 +2601,7 @@ URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0004, "-mpsse", "ARM-USB-OCD", armusbocdtiny) const urj_cable_driver_t urj_tap_cable_ft2232_armusbtiny_h_driver = { - "ARM-USB-OCD-H", + "ARM-USB-TINY-H", N_("Olimex ARM-USB-TINY-H (FT2232H) Cable"), URJ_CABLE_DEVICE_USB, { .usb = ft2232_connect, }, |
From: Janitor <sta...@st...> - 2023-02-14 18:11:21
|
On Tue, Feb 14, 2023 at 12:37:02PM +0100, Benjamin Henrion wrote: > Hi, > > The links to the Doc 0.10 and 0.9 on the mside left menu urjtag.org are > broken, they point to some svn. > > Any plan to put more up to date documentation on there? Yes. The plan is to wait for patches and break the rule of "somebody else should do it". |
From: Benjamin H. <zo...@gm...> - 2023-02-14 11:37:26
|
Hi, The links to the Doc 0.10 and 0.9 on the mside left menu urjtag.org are broken, they point to some svn. Any plan to put more up to date documentation on there? Best, |
From: Geert S. <sta...@st...> - 2023-01-12 22:28:31
|
Hi, Which patches should be added to a new release? Groeten Geert Stappers Janitor of UrJTAG, might have missed some patches. -- Silence is hard to parse |
From: Geert S. <sta...@st...> - 2022-09-30 15:20:52
|
On Tue, Sep 27, 2022 at 01:08:43PM +0200, Peter Pöschl wrote: > Hi, > > the following patch series changes the grammar in src/stapl/jamexp.y to use > precedences. This makes the grammar more efficient (only one reduction to > 'expr' instead of a cascade of reductions to 'logical_or_expr') and easier to > comprehend. > > Patch 1 expands the test suite with additional checks to ascertain what is > allowed on the RHS of pound and dollar tokens and in array range values > (tl;dr: the grammar was too strict, expressions are always allowed). > > Patch 2 provides the changes to jamexp.y > Both applied with a more verbose commit message. Thanks for the contribution to UrJTAG. > Regards, > > Peter Pöschl > Groeten Geert Stappers -- Silence is hard to parse |
From: Peter P. <pp+...@ne...> - 2022-09-27 11:27:00
|
Hi, the following patch series changes the grammar in src/stapl/jamexp.y to use precedences. This makes the grammar more efficient (only one reduction to 'expr' instead of a cascade of reductions to 'logical_or_expr') and easier to comprehend. Patch 1 expands the test suite with additional checks to ascertain what is allowed on the RHS of pound and dollar tokens and in array range values (tl;dr: the grammar was too strict, expressions are always allowed). Patch 2 provides the changes to jamexp.y Regards, Peter Pöschl |
From: Peter P. <pp+...@ne...> - 2022-09-27 11:21:55
|
Signed-off-by: Peter Pöschl <pp+...@ne...> --- urjtag/src/stapl/jamexp.y | 131 ++++++++++++++------------------------ 1 file changed, 48 insertions(+), 83 deletions(-) diff --git a/urjtag/src/stapl/jamexp.y b/urjtag/src/stapl/jamexp.y index 26336271..31a557e5 100644 --- a/urjtag/src/stapl/jamexp.y +++ b/urjtag/src/stapl/jamexp.y @@ -1389,168 +1389,133 @@ JAM_RETURN_TYPE urj_jam_evaluate_expression } } +%left "||" +%left "&&" +%left '|' +%left '^' +%left '&' +%left "==" "!=" +%left '>' '<' ">=" "<=" +%left "<<" ">>" +%left '+' '-' +%left '*' '/' '%' +%precedence UNARY_OP // unary '+', '-', '!', '~' + %% // Grammar rules // grammar start symbol -stapl_expr: /*P1*/ logical_or_expr { +stapl_expr: /*P1*/ expr { urj_jam_parse_value = $1.val; urj_jam_expr_type = $1.type; } ; -pound_expr: /*P2*/ '#' "VALUE"[right] { +int_param: /*P2*/ '#' expr[right] { $$ = CALC (POUND, $right, NULL_EXP); } -; -dollar_expr: /*P3*/ '$' "VALUE"[right] { - $$ = CALC (DOLLAR, $right, NULL_EXP); -} -| '$' array_expr[right] { +| /*P3*/ '$' expr[right] { $$ = CALC (DOLLAR, $right, NULL_EXP); } -; -array_range: /*P4*/ "ARRAY" '[' logical_or_expr[left] ".." logical_or_expr[right] ']' { +| /*P4*/ "ARRAY" '[' expr[left] ".." expr[right] ']' { // ??: ARRAY seems to have been cached somewhere $$ = CALC (ARRAY_RANGE, $left, $right); } -; -array_all: /*P5*/ "ARRAY"[left] '[' ']' { +| /*P5*/ "ARRAY"[left] '[' ']' { $$ = CALC (ARRAY_ALL, $left, NULL_EXP); } ; primary_expr: /*P6*/ "VALUE" -| /*P7*/ '(' logical_or_expr[mid] ')' { +| /*P7*/ '(' expr[mid] ')' { $$ = $mid; } | array_expr -| abs_expr -| ceil_expr -| floor_expr -| int_expr -| log2_expr -| sqrt_expr ; -unary_expr: primary_expr -| /*P8*/ '+' unary_expr[right] { +expr: primary_expr +| /*P8*/ '+' expr[right] %prec UNARY_OP { $$ = $right; } -| /*P9*/ '-' unary_expr[right] { +| /*P9*/ '-' expr[right] %prec UNARY_OP { $$ = CALC (UMINUS, $right, NULL_EXP); } -| /*P10*/ '!' unary_expr[right] { +| /*P10*/ '!' expr[right] %prec UNARY_OP { $$ = CALC (NOT, $right, NULL_EXP); } -| /*P11*/ '~' unary_expr[right] { +| /*P11*/ '~' expr[right] %prec UNARY_OP { $$ = CALC (BITWISE_NOT, $right, NULL_EXP); } -; -additive_expr: multiplicative_expr -| /*P12*/ additive_expr[left] '+' multiplicative_expr[right] { +| /*P12*/ expr[left] '+' expr[right] { $$ = CALC (ADD, $left, $right); } -| /*P13*/ additive_expr[left] '-' multiplicative_expr[right] { +| /*P13*/ expr[left] '-' expr[right] { $$ = CALC (SUB, $left, $right); } -; -multiplicative_expr: unary_expr -| /*P14*/ multiplicative_expr[left] '*' unary_expr[right] { +| /*P14*/ expr[left] '*' expr[right] { $$ = CALC (MULT, $left, $right); } -| /*P15*/ multiplicative_expr[left] '/' unary_expr[right] { +| /*P15*/ expr[left] '/' expr[right] { $$ = CALC (DIV, $left, $right); } -| /*P16*/ multiplicative_expr[left] '%' unary_expr[right] { +| /*P16*/ expr[left] '%' expr[right] { $$ = CALC (MOD, $left, $right); } -; -bitand_expr: equality_expr -| /*P17*/ bitand_expr[left] '&' equality_expr[right] { +| /*P17*/ expr[left] '&' expr[right] { $$ = CALC (BITWISE_AND, $left, $right); } -; -bitor_expr: bitxor_expr -| /*P18*/ bitor_expr[left] '|' bitxor_expr[right] { +| /*P18*/ expr[left] '|' expr[right] { $$ = CALC (BITWISE_OR, $left, $right); } -; -bitxor_expr: bitand_expr -| /*P19*/ bitxor_expr[left] '^' bitand_expr[right] { +| /*P19*/ expr[left] '^' expr[right] { $$ = CALC (BITWISE_XOR, $left, $right); } -; -logical_and_expr: bitor_expr -| /*P20*/ logical_and_expr[left] "&&" bitor_expr[right] { +| /*P20*/ expr[left] "&&" expr[right] { $$ = CALC (AND, $left, $right); } -; -logical_or_expr: logical_and_expr -| /*P21*/ logical_or_expr[left] "||" logical_and_expr[right] { +| /*P21*/ expr[left] "||" expr[right] { $$ = CALC (OR, $left, $right); } -; -shift_expr: additive_expr -| /*P22*/ shift_expr[left] "<<" additive_expr[right] { +| /*P22*/ expr[left] "<<" expr[right] { $$ = CALC (LEFT_SHIFT, $left, $right); } -| /*P23*/ shift_expr[left] ">>" additive_expr[right] { +| /*P23*/ expr[left] ">>" expr[right] { $$ = CALC (RIGHT_SHIFT, $left, $right); } -; -equality_expr: relational_expr -| /*P24*/ equality_expr[left] "==" relational_expr[right] { +| /*P24*/ expr[left] "==" expr[right] { $$ = CALC (EQUALITY, $left, $right); } -| /*P25*/ equality_expr[left] "!=" relational_expr[right] { +| /*P25*/ expr[left] "!=" expr[right] { $$ = CALC (INEQUALITY, $left, $right); } -; -relational_expr: shift_expr -| /*P26*/ relational_expr[left] '>' shift_expr[right] { +| /*P26*/ expr[left] '>' expr[right] { $$ = CALC (GREATER_THAN, $left, $right); } -| /*P27*/ relational_expr[left] '<' shift_expr[right] { +| /*P27*/ expr[left] '<' expr[right] { $$ = CALC (LESS_THAN, $left, $right); } -| /*28*/ relational_expr[left] ">=" shift_expr[right] { +| /*28*/ expr[left] ">=" expr[right] { $$ = CALC (GREATER_OR_EQUAL, $left, $right); } -| /*P29*/ relational_expr[left] "<=" shift_expr[right] { +| /*P29*/ expr[left] "<=" expr[right] { $$ = CALC (LESS_OR_EQUAL, $left, $right); } -; -abs_expr: /*P30*/ "ABS" '(' logical_or_expr[mid] ')' { +| /*P30*/ "ABS" '(' expr[mid] ')' { $$ = CALC (ABS, $mid, NULL_EXP); } -; -int_expr: /*P31*/ "INT" '(' pound_expr[mid] ')' { - $$ = CALC (INT, $mid, NULL_EXP); -} -| "INT" '(' dollar_expr[mid] ')' { - $$ = CALC (INT, $mid, NULL_EXP); -} -| "INT" '(' array_range[mid] ')' { - $$ = CALC (INT, $mid, NULL_EXP); -} -| "INT" '(' array_all[mid] ')' { +| /*P31*/ "INT" '(' int_param[mid] ')' { $$ = CALC (INT, $mid, NULL_EXP); } -; -log2_expr: /*P32*/ "LOG2" '(' logical_or_expr[mid] ')' { +| /*P32*/ "LOG2" '(' expr[mid] ')' { $$ = CALC (LOG2, $mid, NULL_EXP); } -; -sqrt_expr: /*P33*/ "SQRT" '(' logical_or_expr[mid] ')' { +| /*P33*/ "SQRT" '(' expr[mid] ')' { $$ = CALC (SQRT, $mid, NULL_EXP); } -; -ceil_expr: /*P34*/ "CEIL" '(' logical_or_expr[mid] ')' { +| /*P34*/ "CEIL" '(' expr[mid] ')' { $$ = CALC (CIEL, $mid, NULL_EXP); } -; -floor_expr: /*P35*/ "FLOOR" '(' logical_or_expr[mid] ')' { +| /*P35*/ "FLOOR" '(' expr[mid] ')' { $$ = CALC (FLOOR, $mid, NULL_EXP); } ; -array_expr: /*P36*/ "ARRAY"[left] '[' logical_or_expr[right] ']' { +array_expr: /*P36*/ "ARRAY"[left] '[' expr[right] ']' { $$ = CALC (ARRAY, $left, $right); } ; -- 2.35.1 |
From: Peter P. <pp+...@ne...> - 2022-09-27 11:21:37
|
Signed-off-by: Peter Pöschl <pp+...@ne...> --- urjtag/tests/stapl/jamexp_shrd.c | 109 ++++++++++++++++++------------- urjtag/tests/stapl/jamexp_shrd.h | 2 +- 2 files changed, 65 insertions(+), 46 deletions(-) diff --git a/urjtag/tests/stapl/jamexp_shrd.c b/urjtag/tests/stapl/jamexp_shrd.c index 13d283e4..85e32116 100644 --- a/urjtag/tests/stapl/jamexp_shrd.c +++ b/urjtag/tests/stapl/jamexp_shrd.c @@ -123,58 +123,77 @@ struct sEvalExpSpec EvalSpecAry[EVAL_EXP_NRELM] // P1: default START_SYMBOL accept production? // P2: bool literal param of INT function {.expr = "INT(#10001)", .ret_x = JAMC_SUCCESS, .res_x = 17, .typ_x = JAM_INTEGER_EXPR, }, + // pound RHS can be a primary_expr + {.expr = "INT(#(10001))",.ret_x = JAMC_SUCCESS, .res_x = 17, .typ_x = JAM_INTEGER_EXPR, }, + // pound RHS can be an expr + {.expr = "INT(#+10001)", .ret_x = JAMC_SUCCESS, .res_x = 17, .typ_x = JAM_INTEGER_EXPR, }, // P3: bool array ref param of INT function {.expr = "INT($BOOLAFFE_[7])", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // array index can be a primary_expr + {.expr = "INT($BOOLAFFE_[(7)])", .ret_x = JAMC_SUCCESS,.res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // [5] + // array index can be an expr + {.expr = "INT($BOOLAFFE_[+7])", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, // P4: bool array range param of INT function {.expr = "INT(BOOLAFFE_[60..63])", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, + // left array index can be a primary_expr + {.expr = "INT(BOOLAFFE_[(60)..63])", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, + // left array index can be an expr + {.expr = "INT(BOOLAFFE_[+60..63])", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, + // right array index can be a primary_expr + {.expr = "INT(BOOLAFFE_[60..(63)])", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, + // [10] + // right array index can be an expr + {.expr = "INT(BOOLAFFE_[60..+63])", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, // ???? Success from 64-bit bool array? {.expr = "INT(BOOLAFFE_[0..63])", .ret_x = JAMC_SUCCESS, .res_x = -2147450891, .typ_x = JAM_INTEGER_EXPR, }, // P5: bool array param of INT function {.expr = "INT(BOOL_BAFF[])",.ret_x = JAMC_SUCCESS, .res_x = 0x0000baff, .typ_x = JAM_INTEGER_EXPR, }, // P6: good literals and identifiers - // [5] {.expr = "42", .ret_x = JAMC_SUCCESS, .res_x = 42, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + // [15] {.expr = "1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INT_OR_BOOL_EXPR,}, {.expr = "10001", .ret_x = JAMC_SUCCESS, .res_x = 10001, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "2147483647", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, - // [10] #ifdef __code_model_32__ {.expr = "2147483648", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "4294967295", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, + // [20] {.expr = "4294967296", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "4294967297", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "4294967298", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, #else {.expr = "2147483648", .ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "4294967295", .ret_x = JAMC_SUCCESS, .res_x = -1, .typ_x = JAM_INTEGER_EXPR, }, + // [20] {.expr = "4294967296", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INT_OR_BOOL_EXPR,}, {.expr = "4294967297", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INT_OR_BOOL_EXPR,}, {.expr = "4294967298", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR,}, #endif - // [15] {.expr = "BOOL0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "INT23", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + // [25] // P7: parenthesized literals and identifiers {.expr = "(42)", .ret_x = JAMC_SUCCESS, .res_x = 42, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "(0)", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INT_OR_BOOL_EXPR,}, {.expr = "(1)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INT_OR_BOOL_EXPR,}, - // [20] {.expr = "(BOOL0)", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "(INT23)", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + // [30] {.expr = "(1||0)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "(2+3)", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, // P8-P11: prec 1 unary ops +, -, !, ~ {.expr = "+42", .ret_x = JAMC_SUCCESS, .res_x = 42, .typ_x = JAM_INTEGER_EXPR, }, - // [25] {.expr = "+0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INT_OR_BOOL_EXPR,}, {.expr = "+1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + // [35] {.expr = "+BOOL0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "+INT23", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "++INT23", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, - // [30] {.expr = "-42", .ret_x = JAMC_SUCCESS, .res_x = -42, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "-0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // [40] {.expr = "-1", .ret_x = JAMC_SUCCESS, .res_x = -1, .typ_x = JAM_INTEGER_EXPR, }, #ifdef __code_model_32__ {.expr = "-2147483648", .ret_x = JAMC_SUCCESS, .res_x = -2147483647, .typ_x = JAM_INTEGER_EXPR, }, @@ -182,259 +201,258 @@ struct sEvalExpSpec EvalSpecAry[EVAL_EXP_NRELM] {.expr = "-2147483648", .ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, #endif {.expr = "-BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, - // [35] {.expr = "-INT23", .ret_x = JAMC_SUCCESS, .res_x = -23, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "--INT23", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + // [45] {.expr = "-+INT23", .ret_x = JAMC_SUCCESS, .res_x = -23, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "+-INT23", .ret_x = JAMC_SUCCESS, .res_x = -23, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "!42", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, - // [40] {.expr = "!0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "!1", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // [50] {.expr = "!BOOL0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "!INT23", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 23 ^ 0xffffffff, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "!!BOOL0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, - // [45] {.expr = "~42", .ret_x = JAMC_SUCCESS, .res_x = 42 ^ 0xffffffff, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "~0", .ret_x = JAMC_SUCCESS, .res_x = 0xffffffff, .typ_x = JAM_INTEGER_EXPR, }, + // [55] {.expr = "~1", .ret_x = JAMC_SUCCESS, .res_x = 0xfffffffe, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "~BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "~INT23", .ret_x = JAMC_SUCCESS, .res_x = 23 ^ 0xffffffff, .typ_x = JAM_INTEGER_EXPR, }, - // [50] {.expr = "~~42", .ret_x = JAMC_SUCCESS, .res_x = 42, .typ_x = JAM_INTEGER_EXPR, }, // P14-P16: prec 2 binary ops *, /, % {.expr = "2*3", .ret_x = JAMC_SUCCESS, .res_x = 6, .typ_x = JAM_INTEGER_EXPR, }, + // [60] {.expr = "2*INT23", .ret_x = JAMC_SUCCESS, .res_x = 46, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "INT23*2", .ret_x = JAMC_SUCCESS, .res_x = 46, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "INT23*INT23", .ret_x = JAMC_SUCCESS, .res_x = 529, .typ_x = JAM_INTEGER_EXPR, }, - // [55] {.expr = "-2*3", .ret_x = JAMC_SUCCESS, .res_x = -6, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "2*-3", .ret_x = JAMC_SUCCESS, .res_x = -6, .typ_x = JAM_INTEGER_EXPR, }, + // [65] {.expr = "1*BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL0*2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL0*BOOL1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, - // [60] {.expr = "INT23*BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL1*INT23", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [70] {.expr = "2*3*4", .ret_x = JAMC_SUCCESS, .res_x = 24, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "6/2", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "6/4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, - // [65] {.expr = "6/0", .ret_x = JAMC_DIVIDE_BY_ZERO,.res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "6%2", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // [75] // P12-P13: prec 3 binary ops +, - {.expr = "2+3", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "2147483647+1",.ret_x = JAMC_INTEGER_OVERFLOW, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "2+INT23", .ret_x = JAMC_SUCCESS, .res_x = 25, .typ_x = JAM_INTEGER_EXPR, }, - // [70] {.expr = "INT23+2", .ret_x = JAMC_SUCCESS, .res_x = 25, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "INT23+INT23", .ret_x = JAMC_SUCCESS, .res_x = 46, .typ_x = JAM_INTEGER_EXPR, }, + // [80] {.expr = "2+3+4", .ret_x = JAMC_SUCCESS, .res_x = 9, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "2*3+4", .ret_x = JAMC_SUCCESS, .res_x = 10, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "2+3*4", .ret_x = JAMC_SUCCESS, .res_x = 14, .typ_x = JAM_INTEGER_EXPR, }, - // [75] {.expr = "2-3", .ret_x = JAMC_SUCCESS, .res_x = -1, .typ_x = JAM_INTEGER_EXPR, }, #ifdef __code_model_32__ {.expr = "0-2147483648",.ret_x = JAMC_SUCCESS, .res_x = -2147483647, .typ_x = JAM_INTEGER_EXPR, }, #else {.expr = "0-2147483648",.ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, #endif + // [85] {.expr = "S32MIN-1", .ret_x = JAMC_INTEGER_OVERFLOW, .res_x = 0xdead, .typ_x = 0xdead, }, // P22-P23: prec 4 binary ops <<, >> {.expr = "1<<0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1<<30", .ret_x = JAMC_SUCCESS, .res_x = 1073741824, .typ_x = JAM_INTEGER_EXPR, }, - // [80] {.expr = "1<<31", .ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1<<32", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + // [90] {.expr = "1<<33", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1<<34", .ret_x = JAMC_SUCCESS, .res_x = 4, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1<<62", .ret_x = JAMC_SUCCESS, .res_x = 1073741824, .typ_x = JAM_INTEGER_EXPR, }, - // [85] {.expr = "1<<63", .ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1<<1<<2", .ret_x = JAMC_SUCCESS, .res_x = 8, .typ_x = JAM_INTEGER_EXPR, }, + // [95] {.expr = "1+1<<2", .ret_x = JAMC_SUCCESS, .res_x = 8, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1<<2+3", .ret_x = JAMC_SUCCESS, .res_x = 32, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "2>>1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, - // [90] {.expr = "2>>2", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "2>>4", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // [10] {.expr = "S32MIN>>1", .ret_x = JAMC_SUCCESS, .res_x = -1073741824,/*?*/.typ_x = JAM_INTEGER_EXPR, }, {.expr = "S32MIN>>2", .ret_x = JAMC_SUCCESS, .res_x = -536870912, /*?*/.typ_x = JAM_INTEGER_EXPR, }, // P26-P29: prec 5 binary ops >, <, >=, <= {.expr = "2<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, - // [95] {.expr = "0<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "1<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [105] {.expr = "1<4<2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "1<<1<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "1<1<<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, - // [100] {.expr = "1<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "2<=4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [110] {.expr = "2>4", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "2>=4", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, // P24-P25: prec 6 binary ops ==, != {.expr = "2==2", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, - // [105] {.expr = "2==2==2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "2<3==2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [115] {.expr = "2==2<3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "1<<1==2", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "2==1<<1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, - // [110] {.expr = "2!=2", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, // P17: prec 7 binary ops & {.expr = "3&1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + // [120] {.expr = "3&0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1&3", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "0&3", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, - // [115] {.expr = "3&BOOL1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL1&3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [125] {.expr = "BOOL1&BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "3&7==7", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "4==4&3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, - // [120] {.expr = "7&3&2", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1<<1&3", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + // [130] {.expr = "4&1<<2", .ret_x = JAMC_SUCCESS, .res_x = 4, .typ_x = JAM_INTEGER_EXPR, }, // P19: prec 8 binary ops ^ {.expr = "3^1", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "3^0", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, - // [125] {.expr = "1^3", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "0^3", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + // [135] {.expr = "3^BOOL1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL1^3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL1^BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, - // [130] {.expr = "7^3^12", .ret_x = JAMC_SUCCESS, .res_x = 8, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "7^4&12", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + // [140] {.expr = "7&3^12", .ret_x = JAMC_SUCCESS, .res_x = 15, .typ_x = JAM_INTEGER_EXPR, }, // P18: prec 9 binary ops | {.expr = "1|2", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "0|2", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, - // [135] {.expr = "2|1", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "2|0", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + // [145] {.expr = "3|BOOL1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL1|3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL1|BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, - // [140] {.expr = "1|2|4", .ret_x = JAMC_SUCCESS, .res_x = 7, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "1|2^4", .ret_x = JAMC_SUCCESS, .res_x = 7, .typ_x = JAM_INTEGER_EXPR, }, + // [150] {.expr = "1^2|4", .ret_x = JAMC_SUCCESS, .res_x = 7, .typ_x = JAM_INTEGER_EXPR, }, // P20: prec 10 binary ops && {.expr = "1&&1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "1&&0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, - // [145] {.expr = "0&&1", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "0&&0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // [155] {.expr = "BOOL1&&BOOL1",.ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "BOOL1&&BOOL0",.ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "BOOL0&&BOOL1",.ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, - // [150] {.expr = "BOOL0&&BOOL0",.ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "2&&1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [160] {.expr = "1&&2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "2&&2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "1&&1&&1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, - // [155] {.expr = "1|1&&1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "1&&1|1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [165] // P21: prec 11 binary ops || {.expr = "1||1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "1||0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "0||1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, - // [160] {.expr = "0||0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "BOOL1||BOOL1",.ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [170] {.expr = "BOOL1||BOOL0",.ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "BOOL0||BOOL1",.ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "BOOL0||BOOL0",.ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, - // [165] {.expr = "2||1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "1||2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [175] {.expr = "2||2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "1||1||0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "1&&1||0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, - // [170] {.expr = "1||1&&0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "1&&1==1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [180] {.expr = "1==1&&1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, // P30: ABS function {.expr = "ABS(3)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "ABS(-3)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, - // [175] {.expr = "-ABS(3)", .ret_x = JAMC_SUCCESS, .res_x = -3, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "-ABS(3)+3", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // [185] // P31: INT function {.expr = "INT($BOOL0)", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "INT($BOOL1)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "INT($INT23)", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, // P32: LOG2 function - // [180] {.expr = "LOG2(4)", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "LOG2(5)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + // [190] {.expr = "LOG2(6)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "LOG2(7)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "LOG2(8)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, // P33: SQRT function - // [185] {.expr = "SQRT(0)", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "SQRT(1)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + // [195] {.expr = "SQRT(2)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "SQRT(3)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "SQRT(4)", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, // P34: CEIL function - // [190] {.expr = "CEIL(5)", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "CEIL(6/4)", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + // [200] {.expr = "CEIL(SQRT(3))", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, // P35: FLOOR function {.expr = "FLOOR(5)", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "FLOOR(LOG2(4))", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, - // [195] {.expr = "FLOOR(LOG2(5))", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, // P36: array {.expr = "BOOLAFFE_[0]", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // [205] {.expr = "BOOLAFFE_[1]", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "BOOLAFFE_[62]", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, {.expr = "BOOLAFFE_[63]", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, - // [200] {.expr = "INTA5A5_[0]", .ret_x = JAMC_SUCCESS, .res_x = 0xa5a50000, .typ_x = JAM_INTEGER_EXPR, }, {.expr = "INTA5A5_[1]", .ret_x = JAMC_SUCCESS, .res_x = 0xa5a50001, .typ_x = JAM_INTEGER_EXPR, }, + // [210] {.expr = "BOOLAFFE_[-1]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOLAFFE_[64]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOL_BAFF[-1]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, - // [205] {.expr = "BOOL_BAFF[16]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INTA5A5_[-1]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // [215] {.expr = "INTA5A5_[2]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INT_5A5A[-1]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INT_5A5A[3]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, // syntax errors seem to cause failures in subsequent good test steps, put them at the end of the test cases - // [210] {.expr = "INTA5A5_[]", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "BOOLAFFE_[1..2]",.ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // [220] {.expr = "BOOLAFFE_[]", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INT(0)", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INT(1)", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, - // [215] {.expr = "INT(42)", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INT(23+42)", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // [225] {.expr = "INT($BOOLAFFE_[])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INT($BOOLAFFE_[2..3])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, // literal boolean array - bit string {.expr = "#10001", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, - // [220] {.expr = "INT(#10001[0])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INT(#10001[0..2])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // [230] {.expr = "INT(#10001[])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, // array identifiers {.expr = "BOOLAFFE_", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, {.expr = "INT_5A5A", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, - // [225] #ifdef CORE_DUMP // literal boolean array - hex string {.expr = "$42ff", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 10001, .typ_x = JAM_INTEGER_EXPR, }, @@ -442,6 +460,7 @@ struct sEvalExpSpec EvalSpecAry[EVAL_EXP_NRELM] #ifdef FP_EXCEPTION {.expr = "6%0", .ret_x = JAMC_DIVIDE_BY_ZERO,.res_x = 0xdead, .typ_x = 0xdead, }, #endif + // [235] }; //============================================================================ // function prototypes diff --git a/urjtag/tests/stapl/jamexp_shrd.h b/urjtag/tests/stapl/jamexp_shrd.h index 2637b1b8..624285df 100644 --- a/urjtag/tests/stapl/jamexp_shrd.h +++ b/urjtag/tests/stapl/jamexp_shrd.h @@ -19,7 +19,7 @@ + INITSYMARY_NRELM \ ) /// Number of EvalSpecAry elements with expected .ret_x == JAMC_SUCCESS, -#define EVAL_EXP_NRELM_GOOD 164 +#define EVAL_EXP_NRELM_GOOD 172 /// Number of EvalSpecAry elements with expected .ret_x != JAMC_SUCCESS. #define EVAL_EXP_NRELM_BAD 61 /// Number of EvalSpecAry elements -- 2.35.1 |
From: Geert S. <sta...@st...> - 2022-09-24 12:39:37
|
In-Reply-To: <722...@je...> Subject: Re: [UrJTAG-dev] [PATCH 0/4] provide reverse-engineered jamexp.y to generate jamexp.c/jamytab.h On Wed, Sep 21, 2022 at 12:20:21PM +0200, Jean THOMAS via UrJTAG-development wrote: > Le mardi 20 septembre 2022 à 21:20 +0200, Geert Stappers a écrit : > > On Wed, Aug 31, 2022 at 08:33:50AM +0200, Geert Stappers wrote: > > > On Sat, Aug 13, 2022 at 03:13:27PM +0200, Peter Pöschl wrote: > > > > > > > > Patch 1 instruments the existing jamexp.c to report shift/reduce > > > > actions. > > > > Patch 2 adds files to allow writing unit tests with C TAP Harness > > > > Patch 3 adds a unit test program to exercise all productions in > > > > the grammar encoded in the tables of the current jamexp.c. > > > > Patch 4 provides the reverse-engineered jamexp.y and another test > > > > program to verify the grammar in jamexp.y with the test vectors > > > > introduced in patch 3. > > > > .... > > > > > > I'm gonna review the patches. > > > > Short: Applied > > .... In other words: * Patch was send in * Two weeks later: "patch has been seen" notification * Three weeks later: "applied" > > Something else: > > > > Those who want the urjtag project moving faster, > > please express yourself. > > > Hi, > > I agree with Benjamin, SourceForge is dying and a blocker for potential > newcomers to the project. > > I suggest migrating to whatever modern Git forge you prefer (GitHub, > GitLab, SourceHut) and having a mirror on at least GitHub so that > people can contribute there. I have seen many people creating GitHub PR > for UrJTAG. Please provide URLs of those merge requests. ( Because I have missed them, even the reminders of them. ) > I can help with the migration, and arrage for a "premium" SourceHut > account. A nice thing of [sourcehut](https://sourcehut.org) is having [git send-email](https://git-send-email.io/) awareness. I'm fine with SourceHut being an official mirror of UrJTAG git repro. And I prefer a smooth swith over above a big bang migration. We will see how it speeds up UrJTAG development. Frankly: It might be me who is standing in the way :-) > Jean > Regards Geert Stappers Not the same person as when he came to this project. -- Silence is hard to parse |
From: Jean T. <mo...@je...> - 2022-09-21 10:33:05
|
Hi, I agree with Benjamin, SourceForge is dying and a blocker for potential newcomers to the project. I suggest migrating to whatever modern Git forge you prefer (GitHub, GitLab, SourceHut) and having a mirror on at least GitHub so that people can contribute there. I have seen many people creating GitHub PR for UrJTAG. I can help with the migration, and arrage for a "premium" SourceHut account. Jean Le mardi 20 septembre 2022 à 21:20 +0200, Geert Stappers a écrit : > On Wed, Aug 31, 2022 at 08:33:50AM +0200, Geert Stappers wrote: > > On Sat, Aug 13, 2022 at 03:13:27PM +0200, Peter Pöschl wrote: > > > Hi all, > > > > > > I have reverse-engineered a jamexp.y from > > > urjtag/src/stapl/jamexp.c. > > > The following patch series will provide this file and the unit > > > tests I wrote > > > to verify the grammar in the file. > > > > > > Patch 1 instruments the existing jamexp.c to report shift/reduce > > > actions. > > > Patch 2 adds files to allow writing unit tests with C TAP Harness > > > [1]. > > > Patch 3 adds a unit test program to exercise all productions in > > > the grammar > > > encoded in the tables of the current jamexp.c. > > > Patch 4 provides the reverse-engineered jamexp.y and another test > > > program > > > to verify the grammar in jamexp.y with the test vectors > > > introduced > > > in patch 3. > > > In jamexp.y I added an Altera copyright header, because > > > the Lexer- > > > and calculator code is theirs (the headers are reuse [2] > > > compliant). > > > > > > Unfortunately, I have zero experience with Automake, so the > > > integration in the > > > build system is missing. Hopefully somebody from the list will be > > > able to > > > achieve that. Integration hints are in the commit messages of > > > patches 3 and 4. > > > > > > Notes: > > > > > > * jamexp.y currently uses GNU extensions of the YACC syntax, > > > thus requires > > > bison. > > > The reason was to keep the differences between the old jamexp.c > > > and the new > > > jamexp.y as small as possible. > > > > > > * The ordering of the productions in the grammar is suboptimal > > > (the grammar > > > would be much clearer if the productions were ordered > > > differently). > > > The reason is to replicate the production order of the old > > > jamexp.c grammar. > > > > > > * For integration I propose to keep the old jamexp.c and > > > jamytab.h > > > by moving them to tests/stapl/nongen/. This would allow to run > > > the test with both the old and new parser. > > > > > > > I'm gonna review the patches. > > Short: Applied > > > Long: > - patch 1 and 2 were fine > - patch 3 had two trailing spaces, they are removed > - patch 4 had a trailing space, it is removed > - all applied > - Source Forge is the leading git repository > > > Something else: > > Those who want the urjtag project moving faster, > please express yourself. > > > Regards > Geert Stappers > Not the same person as when he came to this project. |
From: Benjamin H. <zo...@gm...> - 2022-09-21 09:36:06
|
Le mar. 20 sept. 2022 à 21:21, Geert Stappers <sta...@st...> a écrit : > On Wed, Aug 31, 2022 at 08:33:50AM +0200, Geert Stappers wrote: > > On Sat, Aug 13, 2022 at 03:13:27PM +0200, Peter Pöschl wrote: > > > Hi all, > > > > > > I have reverse-engineered a jamexp.y from urjtag/src/stapl/jamexp.c. > > > The following patch series will provide this file and the unit tests I > wrote > > > to verify the grammar in the file. > > > > > > Patch 1 instruments the existing jamexp.c to report shift/reduce > actions. > > > Patch 2 adds files to allow writing unit tests with C TAP Harness [1]. > > > Patch 3 adds a unit test program to exercise all productions in the > grammar > > > encoded in the tables of the current jamexp.c. > > > Patch 4 provides the reverse-engineered jamexp.y and another test > program > > > to verify the grammar in jamexp.y with the test vectors > introduced > > > in patch 3. > > > In jamexp.y I added an Altera copyright header, because the > Lexer- > > > and calculator code is theirs (the headers are reuse [2] > compliant). > > > > > > Unfortunately, I have zero experience with Automake, so the > integration in the > > > build system is missing. Hopefully somebody from the list will be able > to > > > achieve that. Integration hints are in the commit messages of patches > 3 and 4. > > > > > > Notes: > > > > > > * jamexp.y currently uses GNU extensions of the YACC syntax, thus > requires > > > bison. > > > The reason was to keep the differences between the old jamexp.c and > the new > > > jamexp.y as small as possible. > > > > > > * The ordering of the productions in the grammar is suboptimal (the > grammar > > > would be much clearer if the productions were ordered differently). > > > The reason is to replicate the production order of the old jamexp.c > grammar. > > > > > > * For integration I propose to keep the old jamexp.c and jamytab.h > > > by moving them to tests/stapl/nongen/. This would allow to run > > > the test with both the old and new parser. > > > > > > > I'm gonna review the patches. > > Short: Applied > > > Long: > - patch 1 and 2 were fine > - patch 3 had two trailing spaces, they are removed > - patch 4 had a trailing space, it is removed > - all applied > - Source Forge is the leading git repository > > > Something else: > > Those who want the urjtag project moving faster, > please express yourself. > Move to Github, Gitlab or Codeberg? Best, |
From: Geert S. <sta...@st...> - 2022-09-20 19:20:44
|
On Wed, Aug 31, 2022 at 08:33:50AM +0200, Geert Stappers wrote: > On Sat, Aug 13, 2022 at 03:13:27PM +0200, Peter Pöschl wrote: > > Hi all, > > > > I have reverse-engineered a jamexp.y from urjtag/src/stapl/jamexp.c. > > The following patch series will provide this file and the unit tests I wrote > > to verify the grammar in the file. > > > > Patch 1 instruments the existing jamexp.c to report shift/reduce actions. > > Patch 2 adds files to allow writing unit tests with C TAP Harness [1]. > > Patch 3 adds a unit test program to exercise all productions in the grammar > > encoded in the tables of the current jamexp.c. > > Patch 4 provides the reverse-engineered jamexp.y and another test program > > to verify the grammar in jamexp.y with the test vectors introduced > > in patch 3. > > In jamexp.y I added an Altera copyright header, because the Lexer- > > and calculator code is theirs (the headers are reuse [2] compliant). > > > > Unfortunately, I have zero experience with Automake, so the integration in the > > build system is missing. Hopefully somebody from the list will be able to > > achieve that. Integration hints are in the commit messages of patches 3 and 4. > > > > Notes: > > > > * jamexp.y currently uses GNU extensions of the YACC syntax, thus requires > > bison. > > The reason was to keep the differences between the old jamexp.c and the new > > jamexp.y as small as possible. > > > > * The ordering of the productions in the grammar is suboptimal (the grammar > > would be much clearer if the productions were ordered differently). > > The reason is to replicate the production order of the old jamexp.c grammar. > > > > * For integration I propose to keep the old jamexp.c and jamytab.h > > by moving them to tests/stapl/nongen/. This would allow to run > > the test with both the old and new parser. > > > > I'm gonna review the patches. Short: Applied Long: - patch 1 and 2 were fine - patch 3 had two trailing spaces, they are removed - patch 4 had a trailing space, it is removed - all applied - Source Forge is the leading git repository Something else: Those who want the urjtag project moving faster, please express yourself. Regards Geert Stappers Not the same person as when he came to this project. -- Silence is hard to parse |
From: Geert S. <sta...@st...> - 2022-08-31 06:52:40
|
On Sat, Aug 13, 2022 at 03:13:27PM +0200, Peter Pöschl wrote: > Hi all, > > I have reverse-engineered a jamexp.y from urjtag/src/stapl/jamexp.c. > The following patch series will provide this file and the unit tests I wrote > to verify the grammar in the file. > > Patch 1 instruments the existing jamexp.c to report shift/reduce actions. > Patch 2 adds files to allow writing unit tests with C TAP Harness [1]. > Patch 3 adds a unit test program to exercise all productions in the grammar > encoded in the tables of the current jamexp.c. > Patch 4 provides the reverse-engineered jamexp.y and another test program > to verify the grammar in jamexp.y with the test vectors introduced > in patch 3. > In jamexp.y I added an Altera copyright header, because the Lexer- > and calculator code is theirs (the headers are reuse [2] compliant). > > Unfortunately, I have zero experience with Automake, so the integration in the > build system is missing. Hopefully somebody from the list will be able to > achieve that. Integration hints are in the commit messages of patches 3 and 4. > > Notes: > > * jamexp.y currently uses GNU extensions of the YACC syntax, thus requires > bison. > The reason was to keep the differences between the old jamexp.c and the new > jamexp.y as small as possible. > > * The ordering of the productions in the grammar is suboptimal (the grammar > would be much clearer if the productions were ordered differently). > The reason is to replicate the production order of the old jamexp.c grammar. > > * For integration I propose to keep the old jamexp.c and jamytab.h > by moving them to tests/stapl/nongen/. This would allow to run > the test with both the old and new parser. > > > Can anybody tell me > > * which packets to install and > * how to call ./configure ./configure It has sane defaults. > to generate 32-bit executables on an amd64 Debian Linux system? Be inside such 32-bit environment. > This is my first foray into the multiarch/multilib area. Acknowledge > I developed the tests with a home-grown build system and managed to create 32- > bit binaries by linking with files from libc6-dev-i386-x32-cross and > lib32gcc-11-dev. > > After './configure --host x86_64-linux-gnux32 --enable-stapl', however, a make > does not produce the desired 32-bit binaries. Sorry for the late response. I'm gonna review the patches. The wish for some special binaries have I seen, it won't get further attention from me. > Best Regards, > > Peter Pöschl Groeten Geert Stappers [1] https://www.eyrie.org/~eagle/software/c-tap-harness [2] https://reuse.software/tutorial -- Silence is hard to parse |
From: Peter P. <pp+...@ne...> - 2022-08-13 13:31:35
|
Hi all, I have reverse-engineered a jamexp.y from urjtag/src/stapl/jamexp.c. The following patch series will provide this file and the unit tests I wrote to verify the grammar in the file. Patch 1 instruments the existing jamexp.c to report shift/reduce actions. Patch 2 adds files to allow writing unit tests with C TAP Harness [1]. Patch 3 adds a unit test program to exercise all productions in the grammar encoded in the tables of the current jamexp.c. Patch 4 provides the reverse-engineered jamexp.y and another test program to verify the grammar in jamexp.y with the test vectors introduced in patch 3. In jamexp.y I added an Altera copyright header, because the Lexer- and calculator code is theirs (the headers are reuse [2] compliant). Unfortunately, I have zero experience with Automake, so the integration in the build system is missing. Hopefully somebody from the list will be able to achieve that. Integration hints are in the commit messages of patches 3 and 4. Notes: * jamexp.y currently uses GNU extensions of the YACC syntax, thus requires bison. The reason was to keep the differences between the old jamexp.c and the new jamexp.y as small as possible. * The ordering of the productions in the grammar is suboptimal (the grammar would be much clearer if the productions were ordered differently). The reason is to replicate the production order of the old jamexp.c grammar. * For integration I propose to keep the old jamexp.c and jamytab.h by moving them to tests/stapl/nongen/. This would allow to run the test with both the old and new parser. Can anybody tell me * which packets to install and * how to call ./configure to generate 32-bit executables on an amd64 Debian Linux system (bookworm/testing)? This is my first foray into the multiarch/multilib area. I developed the tests with a home-grown build system and managed to create 32- bit binaries by linking with files from libc6-dev-i386-x32-cross and lib32gcc-11-dev. After './configure --host x86_64-linux-gnux32 --enable-stapl', however, a make does not produce the desired 32-bit binaries. Best Regards, Peter Pöschl [1] https://www.eyrie.org/~eagle/software/c-tap-harness [2] https://reuse.software/tutorial |
From: Peter P. <pp+...@ne...> - 2022-08-13 13:26:06
|
Note: jamexp.y uses GNU extensions of the YACC grammar as defined by GNU bison Reverse-engineering steps and inputs: * Write a unit test program (driver jamexp_gen.c) using a jamexp.c generated from jamexp.y with bison and the test functions in jamexp_shrd.c ** Copy old jamexp.c to jamexp.y, remove generated tables and replace with directives for the Bison parser generator. ** Use operator precedences from the Stapl specification [1] and the grammar of the C language [2] to derive the grammar for the Stapl expression parser. ** Fix grammar errors by comparing the parser debug outputs with corresponding outputs of the test driver for the non-generated jamexp.c ** Repeat until all tests succeed. [1] http://www.jtagtest.com/pdf/jesd71_stapl.pdf [2] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf Integration hints: * must be compiled as a 32-bit executable ('gcc -m32' was used) * 'export URJ_JAM_YYDEBUG=1' before calling the test driver will generate parser debug information * CPP options: ** -DURJ_JAM_YYDEBUG=1 # debug output from $(BISON_OUT_DIR)/jamexp.c ** --include config.h ** -Iinclude # "urjtag/gettext.h" ** -Isrc/stapl ** -Itests/stapl ** -I. # "tests/tap/macros.h" in tests/tap/basic.c/basic.h ** -I($BISON_OUT_DIR) * Bison options: ** --report=all --warnings=all --debug --defines=$(BISON_OUT_DIR)/jamytab.h * Source files: ** tests/stapl/jamexp_gen.c # defines main() ** src/stapl/jamarray.c ** src/stapl/jamcomp.c ** src/stapl/jamexec.c ** $(BISON_OUT_DIR)/jamexp.c ** src/stapl/jamheap.c ** src/stapl/jamjtag.c ** src/stapl/jamstack.c ** src/stapl/jamsym.c ** tests/stapl/jamexp_shrd.c ** tests/tap/basic.c * Libraries: ** libm Signed-off-by: Peter Pöschl <pp+...@ne...> --- urjtag/src/stapl/jamexp.y | 1556 +++++++++++++++++++++++++++++++ urjtag/tests/stapl/jamexp_gen.c | 35 + 2 files changed, 1591 insertions(+) create mode 100644 urjtag/src/stapl/jamexp.y create mode 100644 urjtag/tests/stapl/jamexp_gen.c diff --git a/urjtag/src/stapl/jamexp.y b/urjtag/src/stapl/jamexp.y new file mode 100644 index 00000000..47f6af4d --- /dev/null +++ b/urjtag/src/stapl/jamexp.y @@ -0,0 +1,1556 @@ +// SPDX-FileCopyrightText: 1997 Altera Corporation +// SPDX-FileCopyrightText: 2022 Peter Poeschl <pp+...@ne...> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +%code top { +#include <stdint.h> +#include <stdio.h> +#include <math.h> +#include "jamexprt.h" +#include "jamdefs.h" +#include "jamexp.h" +#include "jamsym.h" +#include "jamheap.h" +#include "jamarray.h" +#include "jamutil.h" +#include "jamytab.h" +} + +%code { +/* ------------- LEXER DEFINITIONS -----------------------------------------*/ +/****************************************************************************/ +/* */ +/* Operation of GET_FIRST_CH, GET_NEXT_CH, UNGET_CH, and DELETE_CH: */ +/* */ +/* Call GET_FIRST_CH to read a character from mdl_lexer_fp and put it into */ +/* urj_jam_ch and urj_jam_token_buffer. */ +/* */ +/* urj_jam_ch = first char */ +/* urj_jam_token_buffer[0] = first char */ +/* urj_jam_token_buffer[1] = '\0'; */ +/* urj_jam_token_buffer[2] = ? */ +/* urj_jam_token_buffer[3] = ? */ +/* */ +/* Call GET_NEXT_CH to read a character from jam_lexer_fp, put it in */ +/* urj_jam_ch, and append it to urj_jam_token_buffer. */ +/* */ +/* urj_jam_ch = second char */ +/* urj_jam_token_buffer[0] = first char */ +/* urj_jam_token_buffer[1] = second char */ +/* urj_jam_token_buffer[2] = '\0'; */ +/* urj_jam_token_buffer[3] = ? */ +/* */ +/* Call UNGET_CH remove the last character from the buffer but leave it in */ +/* urj_jam_ch and set a flag. (The next call to GET_FIRST_CH will use */ +/* urj_jam_ch as the first char of the token and clear the flag.) */ +/* */ +/* urj_jam_ch = second char */ +/* urj_jam_token_buffer[0] = first char */ +/* urj_jam_token_buffer[1] = '\0'; */ +/* urj_jam_token_buffer[2] = ? */ +/* urj_jam_token_buffer[3] = ? */ +/* */ +/* Call DELETE_CH to remove the last character from the buffer. Use this */ +/* macro to discard the quotes surrounding a string, for example. Unlike */ +/* UNGET_CH, the deleted character will not be reused. */ +/* */ +/****************************************************************************/ + +#define MAX_BUFFER_LENGTH 1024 +#define END_OF_STRING -1 + + + +/****************************************************************************/ +/* */ +/* Operation of BEGIN_MACHINE, END_MACHINE, and ACCEPT: */ +/* */ +/* BEGIN_MACHINE and END_MACHINE should be at the beginning the end of an */ +/* integer function. Inside the function, define states of the machine */ +/* with normal C labels, and jump to states with normal C goto statements. */ +/* Use ACCEPT(token) to return an integer value token to the calling */ +/* routine. */ +/* */ +/* int foo (void) */ +/* { */ +/* BEGIN_MACHINE; */ +/* */ +/* start: */ +/* if (whatever) goto next; */ +/* else goto start; */ +/* */ +/* next: */ +/* if (done) ACCEPT (a_token_id); */ +/* else goto start; */ +/* */ +/* END_MACHINE; */ +/* } */ +/* */ +/* Be sure that there is an ACCEPT() or goto at the end of every state. */ +/* Otherwise, control will "flow" from one state to the next illegally. */ +/* */ +/****************************************************************************/ + +#define BEGIN_MACHINE {int ret + +#define ACCEPT(token) {ret = (token); goto accept;} + +#define END_MACHINE accept: urj_jam_token = ret; \ + } +// need defines, single-chars cannot be %token +#define GREATER_TOK '>' +#define LESS_TOK '<' + +struct +{ + char *string; + int length; + int token; +} static const jam_keyword_table[] = +{ + {"&&", 2, AND_TOK}, + {"||", 2, OR_TOK}, + {"==", 2, EQUALITY_TOK}, + {"!=", 2, INEQUALITY_TOK}, + {">", 2, GREATER_TOK}, + {"<", 2, LESS_TOK}, + {">=", 2, GREATER_EQ_TOK}, + {"<=", 2, LESS_OR_EQ_TOK}, + {"<<", 2, LEFT_SHIFT_TOK}, + {">>", 2, RIGHT_SHIFT_TOK}, + {"..", 2, DOT_DOT_TOK}, + {"OR", 2, OR_TOK}, + {"AND", 3, AND_TOK}, + {"ABS", 3, ABS_TOK}, + {"INT", 3, INT_TOK}, + {"LOG2", 4, LOG2_TOK}, + {"SQRT", 4, SQRT_TOK}, + {"CEIL", 4, CIEL_TOK}, + {"FLOOR", 5, FLOOR_TOK} +}; + +char urj_jam_ch = '\0'; /* next character from input file */ +int urj_jam_strptr = 0; +int urj_jam_token = 0; +char urj_jam_token_buffer[MAX_BUFFER_LENGTH]; +int urj_jam_token_buffer_index; +char urj_jam_parse_string[MAX_BUFFER_LENGTH]; +int32_t urj_jam_parse_value = 0; +int urj_jam_expression_type = 0; +JAMS_SYMBOL_RECORD *urj_jam_array_symbol_rec = NULL; + +#define YYMAXDEPTH 300 /* This fixes a stack depth problem on */ + /* all platforms. */ + +#define YYMAXTLIST 25 /* Max valid next tokens for any state. */ + /* If there are more, error reporting */ + /* will be incomplete. */ + +} + +%code requires { +enum OPERATOR_TYPE +{ + ADD = 0, + SUB, + UMINUS, + MULT, + DIV, + MOD, + NOT, + AND, + OR, + BITWISE_NOT, + BITWISE_AND, + BITWISE_OR, + BITWISE_XOR, + LEFT_SHIFT, + RIGHT_SHIFT, + DOT_DOT, + EQUALITY, + INEQUALITY, + GREATER_THAN, + LESS_THAN, + GREATER_OR_EQUAL, + LESS_OR_EQUAL, + ABS, + INT, + LOG2, + SQRT, + CIEL, + FLOOR, + ARRAY, + POUND, + DOLLAR, + ARRAY_RANGE, + ARRAY_ALL +}; + +typedef enum OPERATOR_TYPE OPERATOR_TYPE; + +typedef struct EXP_STACK +{ + OPERATOR_TYPE child_otype; + JAME_EXPRESSION_TYPE type; + int32_t val; + int32_t loper; /* left and right operands for DIV */ + int32_t roper; /* we save it for CEIL/FLOOR's use */ +} EXPN_STACK; + +#define URJ_JAM_YYSTYPE EXPN_STACK /* must be a #define for yacc */ +} + +%code { +YYSTYPE urj_jam_null_expression = { 0, 0, 0, 0, 0 }; + +JAM_RETURN_TYPE urj_jam_return_code = JAMC_SUCCESS; + +JAME_EXPRESSION_TYPE urj_jam_expr_type = JAM_ILLEGAL_EXPR_TYPE; + +#define NULL_EXP urj_jam_null_expression /* .. for 1 operand operators */ + +#define CALC(operator, lval, rval) urj_jam_exp_eval((operator), (lval), (rval)) +} + +%code provides { +/* --- FUNCTION PROTOTYPES -------------------------------------------- */ + +int urj_jam_yyparse (void); +int urj_jam_yylex (void); +} + +%code { +#ifdef DELME_OLD_TOKEN_VALUES +#define AND_TOK 257 +#define OR_TOK 258 +#define EQUALITY_TOK 259 +#define INEQUALITY_TOK 260 +#define GREATER_TOK 261 +#define LESS_TOK 262 +#define GREATER_EQ_TOK 263 +#define LESS_OR_EQ_TOK 264 +#define LEFT_SHIFT_TOK 265 +#define RIGHT_SHIFT_TOK 266 +#define DOT_DOT_TOK 267 +#define ABS_TOK 268 +#define INT_TOK 269 +#define LOG2_TOK 270 +#define SQRT_TOK 271 +#define CIEL_TOK 272 +#define FLOOR_TOK 273 +#define VALUE_TOK 274 +#define IDENTIFIER_TOK 275 +#define ARRAY_TOK 276 +#define ERROR_TOK 277 +#define UNARY_MINUS 278 +#define UNARY_PLUS 279 +#endif // DELME_OLD_TOKEN_VALUES + +YYSTYPE urj_jam_yylval, urj_jam_yyval; +int32_t urj_jam_convert_bool_to_int (int32_t *data, int32_t msb, int32_t lsb); +EXPN_STACK urj_jam_exp_eval (OPERATOR_TYPE otype, EXPN_STACK op1, EXPN_STACK op2); +void urj_jam_exp_lexer (void); +bool urj_jam_constant_is_ok (const char *string); +bool urj_jam_binary_constant_is_ok (const char *string); +bool urj_jam_hex_constant_is_ok (const char *string); +int32_t urj_jam_atol_bin (char *string); +int32_t urj_jam_atol_hex (char *string); +int urj_jam_constant_value (char *string, int32_t *value); +void urj_jam_yyerror (char *msg); +int urj_jam_yylex (void); +int urj_jam_evaluate_expression (char *expression, int32_t *result, + JAME_EXPRESSION_TYPE *result_type); +int urj_jam_yyparse (void); + +#define GET_FIRST_CH jam_get_first_ch() +#define GET_NEXT_CH jam_get_next_ch() +#define UNGET_CH jam_unget_ch() +#define CH jam_get_ch() +} + +// Bison declarations +%language "C" +//always in current dir: %header "jamytab.h" +//fixed jamexp.h parallel to jamexp.c: %header +// ==> use --defines=$PATH_TO/jamytab.h +%define api.prefix {urj_jam_yy} +%define api.value.type {EXPN_STACK} +%start stapl_expr + +%token AND_TOK "&&" // alias "AND" +%token OR_TOK "||" // alias "OR" +%token EQUALITY_TOK "==" +%token INEQUALITY_TOK "!=" +// single-char cannot be %token +//%token GREATER_TOK '>' +//%token LESS_TOK '<' +%token GREATER_EQ_TOK ">=" +%token LESS_OR_EQ_TOK "<=" +%token LEFT_SHIFT_TOK "<<" +%token RIGHT_SHIFT_TOK ">>" +%token DOT_DOT_TOK ".." +%token ABS_TOK "ABS" +%token INT_TOK "INT" +%token LOG2_TOK "LOG2" +%token SQRT_TOK "SQRT" +%token CIEL_TOK "CEIL" +%token FLOOR_TOK "FLOOR" +%token VALUE_TOK "VALUE" +%token IDENTIFIER_TOK "IDENTIFIER" +%token ARRAY_TOK "ARRAY" +%token ERROR_TOK "ERROR" +%token UNARY_MINUS "UNARY_MINUS" +%token UNARY_PLUS "UNARY_PLUS" + +%code { +static inline void jam_get_next_ch(void) +{ + urj_jam_ch = urj_jam_parse_string[urj_jam_strptr++]; + urj_jam_token_buffer [urj_jam_token_buffer_index++] = urj_jam_ch; + if (urj_jam_token_buffer_index >= MAX_BUFFER_LENGTH) + { + --urj_jam_token_buffer_index; + --urj_jam_strptr; + } + urj_jam_token_buffer [urj_jam_token_buffer_index] = '\0'; +} + +static inline void jam_get_first_ch(void) +{ + urj_jam_token_buffer_index = 0; + jam_get_next_ch(); +} + +static inline void jam_unget_ch(void) +{ + urj_jam_strptr--; + urj_jam_token_buffer[--urj_jam_token_buffer_index] = '\0'; +} + +static inline char jam_get_ch(void) +{ + return urj_jam_ch; +} + +/* +* Used by INT() function to convert Boolean array data to integer. "msb" +* is the index of the most significant bit of the array, and "lsb" is the +* index of the least significant bit. Typically msb > lsb, otherwise the +* bit order will be reversed when converted into integer format. +*/ +int32_t +urj_jam_convert_bool_to_int (int32_t *data, int32_t msb, int32_t lsb) +{ + int32_t i, increment = (msb > lsb) ? 1 : -1; + int32_t mask = 1L, result = 0L; + + msb += increment; + for (i = lsb; i != msb; i += increment) + { + if (data[i >> 5] & (1L << (i & 0x1f))) + result |= mask; + mask <<= 1; + } + + return result; +} + + +/************************************************************************/ +/* */ + +YYSTYPE +urj_jam_exp_eval (OPERATOR_TYPE otype, YYSTYPE op1, YYSTYPE op2) +/* Evaluate op1 OTYPE op2. op1, op2 are operands, OTYPE is operator */ +/* */ +/* Some sneaky things are done to implement CEIL and FLOOR. */ +/* */ +/* We do CEIL of LOG2 by default, and FLOOR of a DIVIDE by default. */ +/* Since we are lazy and we don't want to generate a parse tree, */ +/* we use the parser's reduce actions to tell us when to perform */ +/* an evaluation. But when CEIL and FLOOR are reduced, we know */ +/* nothing about the expression tree beneath it (it's been reduced!) */ +/* */ +/* We keep this information around so we can calculate the CEIL or */ +/* FLOOR. We save value of the operand(s) or a divide in loper and */ +/* roper, then when CEIL/FLOOR get reduced, we just look at their */ +/* values. */ +/* */ +{ + YYSTYPE rtn; + int32_t tmp_val; + JAMS_SYMBOL_RECORD *symbol_rec; + JAMS_HEAP_RECORD *heap_rec; + + rtn.child_otype = 0; + rtn.type = JAM_ILLEGAL_EXPR_TYPE; + rtn.val = 0; + rtn.loper = 0; + rtn.roper = 0; + + switch (otype) + { + case UMINUS: + if ((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + { + rtn.val = -1 * op1.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case ADD: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val + op2.val; + rtn.type = JAM_INTEGER_EXPR; + + /* check for overflow */ + if (((op1.val > 0) && (op2.val > 0) && (rtn.val < 0)) || + ((op1.val < 0) && (op2.val < 0) && (rtn.val > 0))) + { + urj_jam_return_code = JAMC_INTEGER_OVERFLOW; + } + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case SUB: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val - op2.val; + rtn.type = JAM_INTEGER_EXPR; + + /* check for overflow */ + if (((op1.val > 0) && (op2.val < 0) && (rtn.val < 0)) || + ((op1.val < 0) && (op2.val > 0) && (rtn.val > 0))) + { + urj_jam_return_code = JAMC_INTEGER_OVERFLOW; + } + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case MULT: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val * op2.val; + rtn.type = JAM_INTEGER_EXPR; + + /* check for overflow */ + if ((op1.val != 0) && (op2.val != 0) && + (((rtn.val / op1.val) != op2.val) || + ((rtn.val / op2.val) != op1.val))) + { + urj_jam_return_code = JAMC_INTEGER_OVERFLOW; + } + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case DIV: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + if (op2.val != 0) + { + rtn.val = op1.val / op2.val; + rtn.loper = op1.val; + rtn.roper = op2.val; + rtn.child_otype = DIV; /* Save info needed by CEIL */ + rtn.type = JAM_INTEGER_EXPR; + } + else + { + urj_jam_return_code = JAMC_DIVIDE_BY_ZERO; + } + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case MOD: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val % op2.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case NOT: + if ((op1.type == JAM_BOOLEAN_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + { + rtn.val = (op1.val == 0) ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case AND: + if (((op1.type == JAM_BOOLEAN_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_BOOLEAN_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = (op1.val && op2.val) ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case OR: + if (((op1.type == JAM_BOOLEAN_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_BOOLEAN_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = (op1.val || op2.val) ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case BITWISE_NOT: + if ((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + { + rtn.val = ~(uint32_t) op1.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case BITWISE_AND: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val & op2.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case BITWISE_OR: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val | op2.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case BITWISE_XOR: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val ^ op2.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case LEFT_SHIFT: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val << op2.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case RIGHT_SHIFT: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = op1.val >> op2.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case EQUALITY: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = (op1.val == op2.val) ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else if (((op1.type == JAM_BOOLEAN_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_BOOLEAN_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = ((op1.val && op2.val) || ((!op1.val) && (!op2.val))) + ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case INEQUALITY: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = (op1.val == op2.val) ? 0 : 1; + rtn.type = JAM_BOOLEAN_EXPR; + } + else if (((op1.type == JAM_BOOLEAN_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_BOOLEAN_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = ((op1.val && op2.val) || ((!op1.val) && (!op2.val))) + ? 0 : 1; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case GREATER_THAN: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = (op1.val > op2.val) ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case LESS_THAN: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = (op1.val < op2.val) ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case GREATER_OR_EQUAL: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = (op1.val >= op2.val) ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case LESS_OR_EQUAL: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + rtn.val = (op1.val <= op2.val) ? 1 : 0; + rtn.type = JAM_BOOLEAN_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case ABS: + if ((op1.type == JAM_INTEGER_EXPR) || + (op1.type == JAM_INT_OR_BOOL_EXPR)) + { + rtn.val = (op1.val < 0) ? (0 - op1.val) : op1.val; + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case INT: + rtn.val = op1.val; + rtn.type = JAM_INTEGER_EXPR; + break; + + case LOG2: + if ((op1.type == JAM_INTEGER_EXPR) || + (op1.type == JAM_INT_OR_BOOL_EXPR)) + { + if (op1.val > 0) + { + rtn.child_otype = LOG2; + rtn.type = JAM_INTEGER_EXPR; + rtn.loper = op1.val; + tmp_val = op1.val; + rtn.val = 0; + + while (tmp_val != 1) /* ret_val = log2(left_val) */ + { + tmp_val = tmp_val >> 1; + ++rtn.val; + } + + /* if 2^(return_val) isn't the left_val, then the log */ + /* wasn't a perfect integer, so we increment it */ + if (pow (2, rtn.val) != op1.val) + { + ++rtn.val; /* Assume ceil of log2 */ + } + } + else + { + urj_jam_return_code = JAMC_INTEGER_OVERFLOW; + } + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case SQRT: + if ((op1.type == JAM_INTEGER_EXPR) || + (op1.type == JAM_INT_OR_BOOL_EXPR)) + { + if (op1.val >= 0) + { + rtn.child_otype = SQRT; + rtn.type = JAM_INTEGER_EXPR; + rtn.loper = op1.val; + rtn.val = sqrt (op1.val); + } + else + { + urj_jam_return_code = JAMC_INTEGER_OVERFLOW; + } + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case CIEL: + if ((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + { + if (op1.child_otype == DIV) + { + /* Below is true if wasn't perfect divide */ + if ((op1.loper * op1.roper) != op1.val) + { + rtn.val = op1.val + 1; /* add 1 to get CEIL */ + } + else + { + rtn.val = op1.val; + } + } + else if (op1.child_otype == SQRT) + { + /* Below is true if wasn't perfect square-root */ + if ((op1.val * op1.val) < op1.loper) + { + rtn.val = op1.val + 1; /* add 1 to get CEIL */ + } + else + { + rtn.val = op1.val; + } + } + else + { + rtn.val = op1.val; + } + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case FLOOR: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + if (op1.child_otype == LOG2) + { + if (pow (2, op1.val) != op1.loper) + { + rtn.val = op1.val - 1; + } + else + { + rtn.val = op1.val; + } + } + else + { + rtn.val = op1.val; + } + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case ARRAY: + if ((op1.type == JAM_ARRAY_REFERENCE) && + ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + symbol_rec = (JAMS_SYMBOL_RECORD *) op1.val; + urj_jam_return_code = + urj_jam_get_array_value (symbol_rec, op2.val, &rtn.val); + + if (urj_jam_return_code == JAMC_SUCCESS) + { + switch (symbol_rec->type) + { + case JAM_INTEGER_ARRAY_WRITABLE: + case JAM_INTEGER_ARRAY_INITIALIZED: + rtn.type = JAM_INTEGER_EXPR; + break; + + case JAM_BOOLEAN_ARRAY_WRITABLE: + case JAM_BOOLEAN_ARRAY_INITIALIZED: + rtn.type = JAM_BOOLEAN_EXPR; + break; + + default: + urj_jam_return_code = JAMC_INTERNAL_ERROR; + break; + } + } + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case POUND: + rtn.val = op1.val; + rtn.type = JAM_INTEGER_EXPR; + break; + + case DOLLAR: + rtn.val = op1.val; + rtn.type = JAM_INTEGER_EXPR; + break; + + case ARRAY_RANGE: + if (((op1.type == JAM_INTEGER_EXPR) + || (op1.type == JAM_INT_OR_BOOL_EXPR)) + && ((op2.type == JAM_INTEGER_EXPR) + || (op2.type == JAM_INT_OR_BOOL_EXPR))) + { + symbol_rec = urj_jam_array_symbol_rec; + + if ((symbol_rec != NULL) && + ((symbol_rec->type == JAM_BOOLEAN_ARRAY_WRITABLE) || + (symbol_rec->type == JAM_BOOLEAN_ARRAY_INITIALIZED))) + { + heap_rec = (JAMS_HEAP_RECORD *) symbol_rec->value; + + if (heap_rec != NULL) + { + rtn.val = urj_jam_convert_bool_to_int (heap_rec->data, + op1.val, op2.val); + } + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + case ARRAY_ALL: + if (op1.type == JAM_ARRAY_REFERENCE) + { + symbol_rec = (JAMS_SYMBOL_RECORD *) op1.val; + + if ((symbol_rec != NULL) && + ((symbol_rec->type == JAM_BOOLEAN_ARRAY_WRITABLE) || + (symbol_rec->type == JAM_BOOLEAN_ARRAY_INITIALIZED))) + { + heap_rec = (JAMS_HEAP_RECORD *) symbol_rec->value; + + if (heap_rec != NULL) + { + rtn.val = urj_jam_convert_bool_to_int (heap_rec->data, + heap_rec->dimension - + 1, 0); + } + rtn.type = JAM_INTEGER_EXPR; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + } + else + urj_jam_return_code = JAMC_TYPE_MISMATCH; + break; + + default: + urj_jam_return_code = JAMC_INTERNAL_ERROR; + break; + } + + return rtn; +} + + +/****************************************************************************/ +/* */ + +void +urj_jam_exp_lexer (void) +/* */ +/* Description: Lexical analyzer for expressions. */ +/* */ +/* Results are returned in the global variables */ +/* urj_jam_token and urj_jam_token_buffer. */ +/* */ +/* References: Compilers: Principles, Techniques and Tools by ASU */ +/* (the Green Dragon book), section 3.4, Recognition of */ +/* tokens. */ +/* */ +/* Returns: Nothing */ +/* */ +/****************************************************************************/ +{ + BEGIN_MACHINE; + + start: + GET_FIRST_CH; + if (CH == '\0') + ACCEPT (END_OF_STRING) /* Fake an EOF! */ + else if (CH == ' ' || iscntrl (CH)) + goto start; /* white space */ + else if (isalpha (CH)) + goto identifier; + else if (isdigit (CH)) + goto number; + else if (CH == '&') + { + GET_NEXT_CH; + if (CH == '&') + ACCEPT (AND_TOK) + else + { + UNGET_CH; + ACCEPT ('&') + } + } + else if (CH == '|') + { + GET_NEXT_CH; + if (CH == '|') + ACCEPT (OR_TOK) + else + { + UNGET_CH; + ACCEPT ('|') + } + } + else if (CH == '=') + { + GET_NEXT_CH; + if (CH == '=') + ACCEPT (EQUALITY_TOK) + else + { + UNGET_CH; + ACCEPT ('=') + } + } + else if (CH == '!') + { + GET_NEXT_CH; + if (CH == '=') + ACCEPT (INEQUALITY_TOK) + else + { + UNGET_CH; + ACCEPT ('!') + } + } + else if (CH == '>') + { + GET_NEXT_CH; + if (CH == '=') + ACCEPT (GREATER_EQ_TOK) + else + if (CH == '>') + ACCEPT (RIGHT_SHIFT_TOK) + else + { + UNGET_CH; + ACCEPT (GREATER_TOK) + } + } + else if (CH == '<') + { + GET_NEXT_CH; + if (CH == '=') + ACCEPT (LESS_OR_EQ_TOK) + else + if (CH == '<') + ACCEPT (LEFT_SHIFT_TOK) + else + { + UNGET_CH; + ACCEPT (LESS_TOK) + } + } + else if (CH == '.') + { + GET_NEXT_CH; + if (CH == '.') + ACCEPT (DOT_DOT_TOK) + else + { + UNGET_CH; + ACCEPT ('.') + } + } + else + ACCEPT (CH) /* single-chararcter token */ + number: + GET_NEXT_CH; + if (isdigit (CH)) + goto number; + else if (isalpha (CH) || CH == '_') + goto identifier; + else + { + UNGET_CH; + ACCEPT (VALUE_TOK) + } + + identifier: + GET_NEXT_CH; + if (jam_is_name_char(CH)) + goto identifier; + else + { + UNGET_CH; + ACCEPT (IDENTIFIER_TOK) + } + + END_MACHINE; +} + + +/************************************************************************/ +/* */ + +bool +urj_jam_constant_is_ok (const char *string) +/* This routine returns true if the value represented by string is */ +/* a valid signed decimal number. */ +/* */ +{ + size_t ret = strspn (string, "-0123456789"); + return string[ret] == '\0' ? true : false; +} + + +/************************************************************************/ +/* */ + +bool +urj_jam_binary_constant_is_ok (const char *string) +/* This routine returns true if the value represented by string is */ +/* a valid binary number (containing only '0' and '1' characters). */ +/* */ +{ + size_t ret = strspn (string, "10"); + return string[ret] == '\0' ? true : false; +} + + +/************************************************************************/ +/* */ + +bool +urj_jam_hex_constant_is_ok (const char *string) +/* This routine returns true if the value represented by string is */ +/* a valid hexadecimal number. */ +/* */ +{ + size_t ret = strspn (string, "0123456789ABCDEFabcdef"); + return string[ret] == '\0' ? true : false; +} + +int32_t +urj_jam_atol_bin (char *string) +{ + int32_t result = 0L; + int index = 0; + + while ((string[index] == '0') || (string[index] == '1')) + { + result = (result << 1) + (string[index] - '0'); + ++index; + } + + return result; +} + +int32_t +urj_jam_atol_hex (char *string) +{ + int32_t result = 0L; + + sscanf (string, "%x", &result); + + return result; +} + + +/************************************************************************/ +/* */ + +int +urj_jam_constant_value (char *string, int32_t *value) +/* */ +/* This routine converts a string constant into its binary */ +/* value. */ +/* */ +/* Returns true for success, false if the string could not be */ +/* converted. */ +/* */ +{ + int status = false; + + if (urj_jam_expression_type == '#') + { + if (urj_jam_binary_constant_is_ok (string)) + { + *value = urj_jam_atol_bin (string); + urj_jam_expression_type = 0; + status = true; + } + } + else if (urj_jam_expression_type == '$') + { + if (urj_jam_hex_constant_is_ok (string)) + { + *value = urj_jam_atol_hex (string); + urj_jam_expression_type = 0; + status = true; + } + } + else if (urj_jam_constant_is_ok (string)) + { + if (string[0] == '-') + { + *value = 0 - atol (&string[1]); + } + else + { + *value = atol (string); + } + status = true; + } + + return status; +} + + +/************************************************************************/ +/* */ + +void +urj_jam_yyerror (char *msg) +/* */ +/* WARNING: When compiling for YACC 5.0 using err_skel.c, */ +/* this function needs to be modified to be: */ +/* */ +/* urj_jam_yyerror(char *ms1, char *msg2) */ +/* */ +/* urj_jam_yyerror() handles syntax error messages from the parser. */ +/* Since we don't care about anything else but reporting the error, */ +/* just flag the error in urj_jam_return_code. */ +/* */ +{ + msg = msg; /* Avoid compiler warning about msg unused */ + + if (urj_jam_return_code == JAMC_SUCCESS) + urj_jam_return_code = JAMC_SYNTAX_ERROR; +} + + +/************************************************************************/ +/* */ + +int +urj_jam_yylex (void) +/* */ +/* This is the lexer function called by urj_jam_yyparse(). It calls */ +/* urj_jam_exp_lexer() to run as the DFA to return a token in urj_jam_token */ +/* */ +{ + JAMS_SYMBOL_RECORD *symbol_rec = NULL; + int32_t val = 0L; + JAME_EXPRESSION_TYPE type = JAM_ILLEGAL_EXPR_TYPE; + int token_length; + int i; + + urj_jam_exp_lexer (); + + token_length = strlen (urj_jam_token_buffer); + + if (token_length > 1) + { + for (i = 0; i < ARRAY_SIZE(jam_keyword_table); i++) + { + if (token_length == jam_keyword_table[i].length) + { + if (!strcmp + (urj_jam_token_buffer, jam_keyword_table[i].string)) + { + urj_jam_token = jam_keyword_table[i].token; + } + } + } + } + + if (urj_jam_token == VALUE_TOK) + { + if (urj_jam_constant_value (urj_jam_token_buffer, &val)) + { + /* literal 0 and 1 may be interpreted as Integer or Boolean */ + if ((val == 0) || (val == 1)) + { + type = JAM_INT_OR_BOOL_EXPR; + } + else + { + type = JAM_INTEGER_EXPR; + } + } + else + { + urj_jam_return_code = JAMC_SYNTAX_ERROR; + } + } + else if (urj_jam_token == IDENTIFIER_TOK) + { + urj_jam_return_code = + urj_jam_get_symbol_record (urj_jam_token_buffer, &symbol_rec); + + if (urj_jam_return_code == JAMC_SUCCESS) + { + switch (symbol_rec->type) + { + case JAM_INTEGER_SYMBOL: + /* Success, swap token to be a VALUE */ + urj_jam_token = VALUE_TOK; + val = symbol_rec->value; + type = JAM_INTEGER_EXPR; + break; + + case JAM_BOOLEAN_SYMBOL: + /* Success, swap token to be a VALUE */ + urj_jam_token = VALUE_TOK; + val = symbol_rec->value ? 1 : 0; + type = JAM_BOOLEAN_EXPR; + break; + + case JAM_INTEGER_ARRAY_WRITABLE: + case JAM_BOOLEAN_ARRAY_WRITABLE: + case JAM_INTEGER_ARRAY_INITIALIZED: + case JAM_BOOLEAN_ARRAY_INITIALIZED: + /* Success, swap token to be an ARRAY_TOK, */ + /* save pointer to symbol record in value field */ + urj_jam_token = ARRAY_TOK; + val = (int32_t) symbol_rec; + type = JAM_ARRAY_REFERENCE; + urj_jam_array_symbol_rec = symbol_rec; + break; + + default: + urj_jam_return_code = JAMC_SYNTAX_ERROR; + break; + } + } + } + else if (urj_jam_token == '#') + { + urj_jam_expression_type = '#'; + } + else if (urj_jam_token == '$') + { + urj_jam_expression_type = '$'; + } + + urj_jam_yylval.val = val; + urj_jam_yylval.type = type; + urj_jam_yylval.child_otype = 0; + urj_jam_yylval.loper = 0; + urj_jam_yylval.roper = 0; + + return urj_jam_token; +} + + +/************************************************************************/ +/* */ + +JAM_RETURN_TYPE urj_jam_evaluate_expression + (char *expression, int32_t *result, JAME_EXPRESSION_TYPE *result_type) +/* */ +/* THIS IS THE ENTRY POINT INTO THE EXPRESSION EVALUATOR. */ +/* */ +/* s = a string representing the expression to be evaluated. */ +/* (e.g. "2+2+PARAMETER") */ +/* */ +/* status = for returning true if evaluation was successful. */ +/* false if not. */ +/* */ +/* This routine sets up the global variables and then calls */ +/* urj_jam_yyparse() to do the parsing. The reduce actions of the */ +/* parser evaluate the expression. */ +/* */ +/* RETURNS: Value of the expression if success. 0 if FAIL. */ +/* */ +/* Note: One should not rely on the return val to det. success/fail */ +/* since it is possible for, say, "2-2" to be success and */ +/* return 0. */ +/* */ +{ + strcpy (urj_jam_parse_string, expression); + urj_jam_strptr = 0; + urj_jam_token_buffer_index = 0; + urj_jam_return_code = JAMC_SUCCESS; + + urj_jam_yyparse (); + + if (urj_jam_return_code == JAMC_SUCCESS) + { + if (result != 0) + *result = urj_jam_parse_value; + if (result_type != 0) + *result_type = urj_jam_expr_type; + } + + return urj_jam_return_code; +} +} + +%% // Grammar rules + +// grammar start symbol +stapl_expr: /*P1*/ logical_or_expr { + urj_jam_parse_value = $1.val; + urj_jam_expr_type = $1.type; +} +; +pound_expr: /*P2*/ '#' "VALUE"[right] { + $$ = CALC (POUND, $right, NULL_EXP); +} +; +dollar_expr: /*P3*/ '$' "VALUE"[right] { + $$ = CALC (DOLLAR, $right, NULL_EXP); +} +| '$' array_expr[right] { + $$ = CALC (DOLLAR, $right, NULL_EXP); +} +; +array_range: /*P4*/ "ARRAY" '[' logical_or_expr[left] ".." logical_or_expr[right] ']' { + // ??: ARRAY seems to have been cached somewhere + $$ = CALC (ARRAY_RANGE, $left, $right); +} +; +array_all: /*P5*/ "ARRAY"[left] '[' ']' { + $$ = CALC (ARRAY_ALL, $left, NULL_EXP); +} +; +primary_expr: /*P6*/ "VALUE" +| /*P7*/ '(' logical_or_expr[mid] ')' { + $$ = $mid; +} +| array_expr +| abs_expr +| ceil_expr +| floor_expr +| int_expr +| log2_expr +| sqrt_expr +; +unary_expr: primary_expr +| /*P8*/ '+' unary_expr[right] { + $$ = $right; +} +| /*P9*/ '-' unary_expr[right] { + $$ = CALC (UMINUS, $right, NULL_EXP); +} +| /*P10*/ '!' unary_expr[right] { + $$ = CALC (NOT, $right, NULL_EXP); +} +| /*P11*/ '~' unary_expr[right] { + $$ = CALC (BITWISE_NOT, $right, NULL_EXP); +} +; +additive_expr: multiplicative_expr +| /*P12*/ additive_expr[left] '+' multiplicative_expr[right] { + $$ = CALC (ADD, $left, $right); +} +| /*P13*/ additive_expr[left] '-' multiplicative_expr[right] { + $$ = CALC (SUB, $left, $right); +} +; +multiplicative_expr: unary_expr +| /*P14*/ multiplicative_expr[left] '*' unary_expr[right] { + $$ = CALC (MULT, $left, $right); +} +| /*P15*/ multiplicative_expr[left] '/' unary_expr[right] { + $$ = CALC (DIV, $left, $right); +} +| /*P16*/ multiplicative_expr[left] '%' unary_expr[right] { + $$ = CALC (MOD, $left, $right); +} +; +bitand_expr: equality_expr +| /*P17*/ bitand_expr[left] '&' equality_expr[right] { + $$ = CALC (BITWISE_AND, $left, $right); +} +; +bitor_expr: bitxor_expr +| /*P18*/ bitor_expr[left] '|' bitxor_expr[right] { + $$ = CALC (BITWISE_OR, $left, $right); +} +; +bitxor_expr: bitand_expr +| /*P19*/ bitxor_expr[left] '^' bitand_expr[right] { + $$ = CALC (BITWISE_XOR, $left, $right); +} +; +logical_and_expr: bitor_expr +| /*P20*/ logical_and_expr[left] "&&" bitor_expr[right] { + $$ = CALC (AND, $left, $right); +} +; +logical_or_expr: logical_and_expr +| /*P21*/ logical_or_expr[left] "||" logical_and_expr[right] { + $$ = CALC (OR, $left, $right); +} +; +shift_expr: additive_expr +| /*P22*/ shift_expr[left] "<<" additive_expr[right] { + $$ = CALC (LEFT_SHIFT, $left, $right); +} +| /*P23*/ shift_expr[left] ">>" additive_expr[right] { + $$ = CALC (RIGHT_SHIFT, $left, $right); +} +; +equality_expr: relational_expr +| /*P24*/ equality_expr[left] "==" relational_expr[right] { + $$ = CALC (EQUALITY, $left, $right); +} +| /*P25*/ equality_expr[left] "!=" relational_expr[right] { + $$ = CALC (INEQUALITY, $left, $right); +} +; +relational_expr: shift_expr +| /*P26*/ relational_expr[left] '>' shift_expr[right] { + $$ = CALC (GREATER_THAN, $left, $right); +} +| /*P27*/ relational_expr[left] '<' shift_expr[right] { + $$ = CALC (LESS_THAN, $left, $right); +} +| /*28*/ relational_expr[left] ">=" shift_expr[right] { + $$ = CALC (GREATER_OR_EQUAL, $left, $right); +} +| /*P29*/ relational_expr[left] "<=" shift_expr[right] { + $$ = CALC (LESS_OR_EQUAL, $left, $right); +} +; +abs_expr: /*P30*/ "ABS" '(' logical_or_expr[mid] ')' { + $$ = CALC (ABS, $mid, NULL_EXP); +} +; +int_expr: /*P31*/ "INT" '(' pound_expr[mid] ')' { + $$ = CALC (INT, $mid, NULL_EXP); +} +| "INT" '(' dollar_expr[mid] ')' { + $$ = CALC (INT, $mid, NULL_EXP); +} +| "INT" '(' array_range[mid] ')' { + $$ = CALC (INT, $mid, NULL_EXP); +} +| "INT" '(' array_all[mid] ')' { + $$ = CALC (INT, $mid, NULL_EXP); +} +; +log2_expr: /*P32*/ "LOG2" '(' logical_or_expr[mid] ')' { + $$ = CALC (LOG2, $mid, NULL_EXP); +} +; +sqrt_expr: /*P33*/ "SQRT" '(' logical_or_expr[mid] ')' { + $$ = CALC (SQRT, $mid, NULL_EXP); +} +; +ceil_expr: /*P34*/ "CEIL" '(' logical_or_expr[mid] ')' { + $$ = CALC (CIEL, $mid, NULL_EXP); +} +; +floor_expr: /*P35*/ "FLOOR" '(' logical_or_expr[mid] ')' { + $$ = CALC (FLOOR, $mid, NULL_EXP); +} +; +array_expr: /*P36*/ "ARRAY"[left] '[' logical_or_expr[right] ']' { + $$ = CALC (ARRAY, $left, $right); +} +; diff --git a/urjtag/tests/stapl/jamexp_gen.c b/urjtag/tests/stapl/jamexp_gen.c new file mode 100644 index 00000000..65d599c0 --- /dev/null +++ b/urjtag/tests/stapl/jamexp_gen.c @@ -0,0 +1,35 @@ +/** + * \author SPDX-FileCopyrightText: 2022 Peter Poeschl <pp+...@ne...> + * + * \copyright SPDX-License-Identifier: GPL-2.0-or-later + * + * \file jamexp_gen.c + * \brief Unit test program for jamexp.c generated by Bison from jamexp.y + * + * Test idea: + * * assume non-generated jamexp.c is correct + * * create tests for urj_jam_evaluate_expression() to exercise all productions + * * use the same test vectors to validate syntax in jamexp.c generated from + * jamexp.y + */ + +#include "jamexp_shrd.h" +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include "jamdefs.h" +#include "jamytab.h" + +#include "tap/basic.h" + +int main(void) +{ +#if URJ_JAM_YYDEBUG + const char *const env_URJ_JAM_YYDEBUG = getenv("URJ_JAM_YYDEBUG"); + urj_jam_yydebug + = env_URJ_JAM_YYDEBUG && !strcmp(env_URJ_JAM_YYDEBUG, "1"); +#endif + plan(PLAN_TESTS); + + check__urj_jam_evaluate_expression(); +} -- 2.35.1 |
From: Peter P. <pp+...@ne...> - 2022-08-13 13:26:00
|
Reverse-engineering steps and inputs: * Write table dumper program to produce output similar to 'bison --report' ** Create main program from code in [1] ** copy in tables jam_yyexca ... jam_yydef from jamexp.c ** add glue-defines ** add string arrays for better output * Write a unit test program (jamexp_shrd.*, driver jamexp_nongen.c) using C-tap-harness [2] ** Instrument jamexp.c to report parser shift/reduce actions ** Deriving the full grammar from the table dumper program was too much tedious work, therefore ** use the Stapl specification [3] and token table to find the possible operators ** write tests for simple (typically one-operator) expressions. This exercised most of the productions except the ones involving array variables. Up to this point the unit test program was a 64-bit Linux executable. ** Now the build environment needed to be changed to generate a 32-bit executable because pointers are casted to/from int32_t causing core-dumps with 64-bit executables. Observation: after the conversion some tests involving integers near INT32_MIN, INT32_MAX produced different results. Corresponding tests were fixed and by conditionally compiling with '#ifdef __code_model_32__' ** Analysing the output of the table dumper program yielded test inputs for array expressions, finally exercising all productions of the grammar. [1] https://stackoverflow.com/questions/20496216/retrieve-the-grammar-rules-from-the-generated-parsing-tables [2] git://git.eyrie.org/devel/c-tap-harness.git [3] http://www.jtagtest.com/pdf/jesd71_stapl.pdf Integration hints: * must be compiled as a 32-bit executable ('gcc -m32' was used) * CPP options: ** -DURJ_JAM_YYDEBUG # debug output from src/stapl/jamexp.c ** --include config.h ** -Iinclude # "urjtag/gettext.h" ** -Isrc/stapl ** -Itests/stapl ** -I. # "tests/tap/macros.h" in tests/tap/basic.c/basic.h * Source files: ** tests/stapl/jamexp_nongen.c # defines main() ** src/stapl/jamarray.c ** src/stapl/jamcomp.c ** src/stapl/jamexec.c ** src/stapl/jamexp.c # old non-generated version ** src/stapl/jamheap.c ** src/stapl/jamjtag.c ** src/stapl/jamstack.c ** src/stapl/jamsym.c ** tests/stapl/jamexp_shrd.c ** tests/tap/basic.c * Libraries: ** libm Signed-off-by: Peter Pöschl <pp+...@ne...> --- urjtag/tests/stapl/jamexp_nongen.c | 25 ++ urjtag/tests/stapl/jamexp_shrd.c | 649 +++++++++++++++++++++++++++++ urjtag/tests/stapl/jamexp_shrd.h | 45 ++ 3 files changed, 719 insertions(+) create mode 100644 urjtag/tests/stapl/jamexp_nongen.c create mode 100644 urjtag/tests/stapl/jamexp_shrd.c create mode 100644 urjtag/tests/stapl/jamexp_shrd.h diff --git a/urjtag/tests/stapl/jamexp_nongen.c b/urjtag/tests/stapl/jamexp_nongen.c new file mode 100644 index 00000000..34f3dbdb --- /dev/null +++ b/urjtag/tests/stapl/jamexp_nongen.c @@ -0,0 +1,25 @@ +/** + * \author SPDX-FileCopyrightText: 2022 Peter Poeschl <pp+...@ne...> + * + * \copyright SPDX-License-Identifier: GPL-2.0-or-later + * + * \file jamexp_nongen.c + * \brief Unit test program for non-generated stapl/jamexp.c + * + * Test idea: + * * Assume jamexp.c is correct + * * Create tests for urj_jam_evaluate_expression() to exercise all productions + * * From the output of an instrumented jamexp.c it should be possible to + * reverse-engineer a GNU bison grammar file jamexp.y. + */ + +#include "jamexp_shrd.h" +#include "tap/basic.h" + +int main(void) +{ + plan(PLAN_TESTS); + + check__urj_jam_evaluate_expression(); + +} diff --git a/urjtag/tests/stapl/jamexp_shrd.c b/urjtag/tests/stapl/jamexp_shrd.c new file mode 100644 index 00000000..13d283e4 --- /dev/null +++ b/urjtag/tests/stapl/jamexp_shrd.c @@ -0,0 +1,649 @@ +/** + * \author SPDX-FileCopyrightText: 2022 Peter Poeschl <pp+...@ne...> + * + * \copyright SPDX-License-Identifier: GPL-2.0-or-later + * + * \file jamexp_shrd.c + * \brief Common test function to check urj_jam_evaluate_expression() results. + * + * Test idea: + * * check all functions in jamexp.c directly or indirectly called by + * urj_jam_evaluate_expression(). + * * exercise all productions in the parser. + * * check result values + * * tests shared between drivers using generated of non-generated jamexp.c. + */ + +#include "jamexp_shrd.h" +#include "jamdefs.h" +#include "jamexprt.h" +#include "jamsym.h" +#include "jamexp.h" +#include "jamheap.h" +#include "jamjtag.h" +#include "jamstack.h" + +#include "tap/basic.h" + +//============================================================================ +// constants +//============================================================================ + + +//============================================================================ +// data types +//============================================================================ + +struct JAMS_HEAP_STRUCT2 +{ + struct JAMS_HEAP_STRUCT *next; + JAMS_SYMBOL_RECORD *symbol_record; + JAME_BOOLEAN_REP rep; /* data representation format */ + BOOL cached; /* true if array data is cached */ + int32_t dimension; /* number of elements in array */ + int32_t position; /* position in file of initialization data */ + int32_t data[2]; /* first word of data (or cache buffer) */ + +}; +struct JAMS_HEAP_STRUCT3 +{ + struct JAMS_HEAP_STRUCT *next; + JAMS_SYMBOL_RECORD *symbol_record; + JAME_BOOLEAN_REP rep; /* data representation format */ + BOOL cached; /* true if array data is cached */ + int32_t dimension; /* number of elements in array */ + int32_t position; /* position in file of initialization data */ + int32_t data[3]; /* first word of data (or cache buffer) */ + +}; + +struct sEvalExpSpec { + /// expression string to evaluate + const char * expr; + /// expected function return value + JAM_RETURN_TYPE ret_x; + /// expected expression result + int32_t res_x; + /** expected type of res_x + * JAM_ILLEGAL_EXPR_TYPE = 0, + * JAM_INTEGER_EXPR, + * JAM_BOOLEAN_EXPR, + * JAM_INT_OR_BOOL_EXPR, + * JAM_ARRAY_REFERENCE, + * JAM_EXPR_MAX + */ + JAME_EXPRESSION_TYPE typ_x; +}; + +struct sInitSym { + JAME_SYMBOL_TYPE type; + char *name; + intptr_t value; +}; + +static struct JAMS_HEAP_STRUCT2 BoolAffe_64 = { + .cached = false, + .dimension = 64, // bits + .data = {0xaffe0000, 0xaffe0001}, +}; +static struct JAMS_HEAP_STRUCT BoolBaff_16 = { + .cached = false, + .dimension = 16, // bits + .data = {0x0000baff}, +}; +static struct JAMS_HEAP_STRUCT2 IntA5A5_2 = { + .cached = false, + .dimension = 2, // uint32_t elems + .data = {0xa5a50000, 0xa5a50001}, +}; +static struct JAMS_HEAP_STRUCT3 Int5A5A_3 = { + .cached = false, + .dimension = 3, // uint32_t elems + .data = {0x5a5a0000, 0x5a5a0001, 0x5a5a0002}, +}; + +static const struct sInitSym InitSymAry[INITSYMARY_NRELM] = { + {JAM_BOOLEAN_SYMBOL, "BOOL0", 0}, + {JAM_BOOLEAN_SYMBOL, "BOOL1", 1}, + {JAM_INTEGER_SYMBOL, "INT0", 0}, + {JAM_INTEGER_SYMBOL, "INT1", 1}, + {JAM_INTEGER_SYMBOL, "INT23", 23}, + {JAM_INTEGER_SYMBOL, "S32MAX", 2147483647}, // 0x7fffffff + {JAM_INTEGER_SYMBOL, "U32MAX", 4294967295}, // 0xffffffff + {JAM_INTEGER_SYMBOL, "S32MIN", -2147483648}, // 0x80000000 + {JAM_BOOLEAN_ARRAY_INITIALIZED, "BOOLAFFE_", (intptr_t) &BoolAffe_64}, + {JAM_BOOLEAN_ARRAY_INITIALIZED, "BOOL_BAFF", (intptr_t) &BoolBaff_16}, + {JAM_INTEGER_ARRAY_INITIALIZED, "INTA5A5_", (intptr_t) &IntA5A5_2}, + {JAM_INTEGER_ARRAY_INITIALIZED, "INT_5A5A", (intptr_t) &Int5A5A_3}, +}; + +struct sEvalExpSpec EvalSpecAry[EVAL_EXP_NRELM] += { + // [0] + // P1: default START_SYMBOL accept production? + // P2: bool literal param of INT function + {.expr = "INT(#10001)", .ret_x = JAMC_SUCCESS, .res_x = 17, .typ_x = JAM_INTEGER_EXPR, }, + // P3: bool array ref param of INT function + {.expr = "INT($BOOLAFFE_[7])", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // P4: bool array range param of INT function + {.expr = "INT(BOOLAFFE_[60..63])", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, + // ???? Success from 64-bit bool array? + {.expr = "INT(BOOLAFFE_[0..63])", .ret_x = JAMC_SUCCESS, .res_x = -2147450891, .typ_x = JAM_INTEGER_EXPR, }, + // P5: bool array param of INT function + {.expr = "INT(BOOL_BAFF[])",.ret_x = JAMC_SUCCESS, .res_x = 0x0000baff, .typ_x = JAM_INTEGER_EXPR, }, + // P6: good literals and identifiers + // [5] + {.expr = "42", .ret_x = JAMC_SUCCESS, .res_x = 42, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + {.expr = "1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + {.expr = "10001", .ret_x = JAMC_SUCCESS, .res_x = 10001, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2147483647", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, + // [10] +#ifdef __code_model_32__ + {.expr = "2147483648", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "4294967295", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "4294967296", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "4294967297", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "4294967298", .ret_x = JAMC_SUCCESS, .res_x = 2147483647, .typ_x = JAM_INTEGER_EXPR, }, +#else + {.expr = "2147483648", .ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "4294967295", .ret_x = JAMC_SUCCESS, .res_x = -1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "4294967296", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + {.expr = "4294967297", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + {.expr = "4294967298", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR,}, +#endif + // [15] + {.expr = "BOOL0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "INT23", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + // P7: parenthesized literals and identifiers + {.expr = "(42)", .ret_x = JAMC_SUCCESS, .res_x = 42, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "(0)", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + {.expr = "(1)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + // [20] + {.expr = "(BOOL0)", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "(INT23)", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "(1||0)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "(2+3)", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, + // P8-P11: prec 1 unary ops +, -, !, ~ + {.expr = "+42", .ret_x = JAMC_SUCCESS, .res_x = 42, .typ_x = JAM_INTEGER_EXPR, }, + // [25] + {.expr = "+0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + {.expr = "+1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INT_OR_BOOL_EXPR,}, + {.expr = "+BOOL0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "+INT23", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "++INT23", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + // [30] + {.expr = "-42", .ret_x = JAMC_SUCCESS, .res_x = -42, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "-0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "-1", .ret_x = JAMC_SUCCESS, .res_x = -1, .typ_x = JAM_INTEGER_EXPR, }, +#ifdef __code_model_32__ + {.expr = "-2147483648", .ret_x = JAMC_SUCCESS, .res_x = -2147483647, .typ_x = JAM_INTEGER_EXPR, }, +#else + {.expr = "-2147483648", .ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, +#endif + {.expr = "-BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [35] + {.expr = "-INT23", .ret_x = JAMC_SUCCESS, .res_x = -23, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "--INT23", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "-+INT23", .ret_x = JAMC_SUCCESS, .res_x = -23, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "+-INT23", .ret_x = JAMC_SUCCESS, .res_x = -23, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "!42", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [40] + {.expr = "!0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "!1", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "!BOOL0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "!INT23", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 23 ^ 0xffffffff, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "!!BOOL0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // [45] + {.expr = "~42", .ret_x = JAMC_SUCCESS, .res_x = 42 ^ 0xffffffff, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "~0", .ret_x = JAMC_SUCCESS, .res_x = 0xffffffff, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "~1", .ret_x = JAMC_SUCCESS, .res_x = 0xfffffffe, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "~BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "~INT23", .ret_x = JAMC_SUCCESS, .res_x = 23 ^ 0xffffffff, .typ_x = JAM_INTEGER_EXPR, }, + // [50] + {.expr = "~~42", .ret_x = JAMC_SUCCESS, .res_x = 42, .typ_x = JAM_INTEGER_EXPR, }, + // P14-P16: prec 2 binary ops *, /, % + {.expr = "2*3", .ret_x = JAMC_SUCCESS, .res_x = 6, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2*INT23", .ret_x = JAMC_SUCCESS, .res_x = 46, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "INT23*2", .ret_x = JAMC_SUCCESS, .res_x = 46, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "INT23*INT23", .ret_x = JAMC_SUCCESS, .res_x = 529, .typ_x = JAM_INTEGER_EXPR, }, + // [55] + {.expr = "-2*3", .ret_x = JAMC_SUCCESS, .res_x = -6, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2*-3", .ret_x = JAMC_SUCCESS, .res_x = -6, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1*BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL0*2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL0*BOOL1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [60] + {.expr = "INT23*BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL1*INT23", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "2*3*4", .ret_x = JAMC_SUCCESS, .res_x = 24, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "6/2", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "6/4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + // [65] + {.expr = "6/0", .ret_x = JAMC_DIVIDE_BY_ZERO,.res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "6%2", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // P12-P13: prec 3 binary ops +, - + {.expr = "2+3", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2147483647+1",.ret_x = JAMC_INTEGER_OVERFLOW, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "2+INT23", .ret_x = JAMC_SUCCESS, .res_x = 25, .typ_x = JAM_INTEGER_EXPR, }, + // [70] + {.expr = "INT23+2", .ret_x = JAMC_SUCCESS, .res_x = 25, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "INT23+INT23", .ret_x = JAMC_SUCCESS, .res_x = 46, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2+3+4", .ret_x = JAMC_SUCCESS, .res_x = 9, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2*3+4", .ret_x = JAMC_SUCCESS, .res_x = 10, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2+3*4", .ret_x = JAMC_SUCCESS, .res_x = 14, .typ_x = JAM_INTEGER_EXPR, }, + // [75] + {.expr = "2-3", .ret_x = JAMC_SUCCESS, .res_x = -1, .typ_x = JAM_INTEGER_EXPR, }, +#ifdef __code_model_32__ + {.expr = "0-2147483648",.ret_x = JAMC_SUCCESS, .res_x = -2147483647, .typ_x = JAM_INTEGER_EXPR, }, +#else + {.expr = "0-2147483648",.ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, +#endif + {.expr = "S32MIN-1", .ret_x = JAMC_INTEGER_OVERFLOW, .res_x = 0xdead, .typ_x = 0xdead, }, + // P22-P23: prec 4 binary ops <<, >> + {.expr = "1<<0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1<<30", .ret_x = JAMC_SUCCESS, .res_x = 1073741824, .typ_x = JAM_INTEGER_EXPR, }, + // [80] + {.expr = "1<<31", .ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1<<32", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1<<33", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1<<34", .ret_x = JAMC_SUCCESS, .res_x = 4, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1<<62", .ret_x = JAMC_SUCCESS, .res_x = 1073741824, .typ_x = JAM_INTEGER_EXPR, }, + // [85] + {.expr = "1<<63", .ret_x = JAMC_SUCCESS, .res_x = -2147483648, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1<<1<<2", .ret_x = JAMC_SUCCESS, .res_x = 8, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1+1<<2", .ret_x = JAMC_SUCCESS, .res_x = 8, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1<<2+3", .ret_x = JAMC_SUCCESS, .res_x = 32, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2>>1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + // [90] + {.expr = "2>>2", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2>>4", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "S32MIN>>1", .ret_x = JAMC_SUCCESS, .res_x = -1073741824,/*?*/.typ_x = JAM_INTEGER_EXPR, }, + {.expr = "S32MIN>>2", .ret_x = JAMC_SUCCESS, .res_x = -536870912, /*?*/.typ_x = JAM_INTEGER_EXPR, }, + // P26-P29: prec 5 binary ops >, <, >=, <= + {.expr = "2<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [95] + {.expr = "0<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "1<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "1<4<2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "1<<1<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "1<1<<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [100] + {.expr = "1<4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "2<=4", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "2>4", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "2>=4", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // P24-P25: prec 6 binary ops ==, != + {.expr = "2==2", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [105] + {.expr = "2==2==2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "2<3==2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "2==2<3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "1<<1==2", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "2==1<<1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [110] + {.expr = "2!=2", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // P17: prec 7 binary ops & + {.expr = "3&1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "3&0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1&3", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "0&3", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // [115] + {.expr = "3&BOOL1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL1&3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL1&BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "3&7==7", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "4==4&3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [120] + {.expr = "7&3&2", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1<<1&3", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "4&1<<2", .ret_x = JAMC_SUCCESS, .res_x = 4, .typ_x = JAM_INTEGER_EXPR, }, + // P19: prec 8 binary ops ^ + {.expr = "3^1", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "3^0", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + // [125] + {.expr = "1^3", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "0^3", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "3^BOOL1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL1^3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL1^BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [130] + {.expr = "7^3^12", .ret_x = JAMC_SUCCESS, .res_x = 8, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "7^4&12", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "7&3^12", .ret_x = JAMC_SUCCESS, .res_x = 15, .typ_x = JAM_INTEGER_EXPR, }, + // P18: prec 9 binary ops | + {.expr = "1|2", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "0|2", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + // [135] + {.expr = "2|1", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "2|0", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "3|BOOL1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL1|3", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL1|BOOL0", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [140] + {.expr = "1|2|4", .ret_x = JAMC_SUCCESS, .res_x = 7, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1|2^4", .ret_x = JAMC_SUCCESS, .res_x = 7, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "1^2|4", .ret_x = JAMC_SUCCESS, .res_x = 7, .typ_x = JAM_INTEGER_EXPR, }, + // P20: prec 10 binary ops && + {.expr = "1&&1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "1&&0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // [145] + {.expr = "0&&1", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "0&&0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOL1&&BOOL1",.ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOL1&&BOOL0",.ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOL0&&BOOL1",.ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // [150] + {.expr = "BOOL0&&BOOL0",.ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "2&&1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "1&&2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "2&&2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "1&&1&&1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [155] + {.expr = "1|1&&1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "1&&1|1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // P21: prec 11 binary ops || + {.expr = "1||1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "1||0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "0||1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [160] + {.expr = "0||0", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOL1||BOOL1",.ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOL1||BOOL0",.ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOL0||BOOL1",.ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOL0||BOOL0",.ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + // [165] + {.expr = "2||1", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "1||2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "2||2", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "1||1||0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "1&&1||0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [170] + {.expr = "1||1&&0", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "1&&1==1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "1==1&&1", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // P30: ABS function + {.expr = "ABS(3)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "ABS(-3)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + // [175] + {.expr = "-ABS(3)", .ret_x = JAMC_SUCCESS, .res_x = -3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "-ABS(3)+3", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + // P31: INT function + {.expr = "INT($BOOL0)", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "INT($BOOL1)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "INT($INT23)", .ret_x = JAMC_SUCCESS, .res_x = 23, .typ_x = JAM_INTEGER_EXPR, }, + // P32: LOG2 function + // [180] + {.expr = "LOG2(4)", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "LOG2(5)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "LOG2(6)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "LOG2(7)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "LOG2(8)", .ret_x = JAMC_SUCCESS, .res_x = 3, .typ_x = JAM_INTEGER_EXPR, }, + // P33: SQRT function + // [185] + {.expr = "SQRT(0)", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "SQRT(1)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "SQRT(2)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "SQRT(3)", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "SQRT(4)", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + // P34: CEIL function + // [190] + {.expr = "CEIL(5)", .ret_x = JAMC_SUCCESS, .res_x = 5, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "CEIL(6/4)", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "CEIL(SQRT(3))", .ret_x = JAMC_SUCCESS, .res_x = 2, .typ_x = JAM_INTEGER_EXPR, }, + // P35: FLOOR function + {.expr = "FLOOR(5)", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "FLOOR(LOG2(4))", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // [195] + {.expr = "FLOOR(LOG2(5))", .ret_x = JAMC_TYPE_MISMATCH, .res_x = 0xdead, .typ_x = 0xdead, }, + // P36: array + {.expr = "BOOLAFFE_[0]", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOLAFFE_[1]", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOLAFFE_[62]", .ret_x = JAMC_SUCCESS, .res_x = 0, .typ_x = JAM_BOOLEAN_EXPR, }, + {.expr = "BOOLAFFE_[63]", .ret_x = JAMC_SUCCESS, .res_x = 1, .typ_x = JAM_BOOLEAN_EXPR, }, + // [200] + {.expr = "INTA5A5_[0]", .ret_x = JAMC_SUCCESS, .res_x = 0xa5a50000, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "INTA5A5_[1]", .ret_x = JAMC_SUCCESS, .res_x = 0xa5a50001, .typ_x = JAM_INTEGER_EXPR, }, + {.expr = "BOOLAFFE_[-1]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOLAFFE_[64]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOL_BAFF[-1]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // [205] + {.expr = "BOOL_BAFF[16]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INTA5A5_[-1]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INTA5A5_[2]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT_5A5A[-1]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT_5A5A[3]", .ret_x = JAMC_BOUNDS_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // syntax errors seem to cause failures in subsequent good test steps, put them at the end of the test cases + // [210] + {.expr = "INTA5A5_[]", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOLAFFE_[1..2]",.ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "BOOLAFFE_[]", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT(0)", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT(1)", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // [215] + {.expr = "INT(42)", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT(23+42)", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT($BOOLAFFE_[])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT($BOOLAFFE_[2..3])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // literal boolean array - bit string + {.expr = "#10001", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // [220] + {.expr = "INT(#10001[0])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT(#10001[0..2])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT(#10001[])", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // array identifiers + {.expr = "BOOLAFFE_", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + {.expr = "INT_5A5A", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 0xdead, .typ_x = 0xdead, }, + // [225] +#ifdef CORE_DUMP + // literal boolean array - hex string + {.expr = "$42ff", .ret_x = JAMC_SYNTAX_ERROR, .res_x = 10001, .typ_x = JAM_INTEGER_EXPR, }, +#endif +#ifdef FP_EXCEPTION + {.expr = "6%0", .ret_x = JAMC_DIVIDE_BY_ZERO,.res_x = 0xdead, .typ_x = 0xdead, }, +#endif +}; +//============================================================================ +// function prototypes +//============================================================================ + +//============================================================================ +// local variables +//============================================================================ + +//============================================================================ +// global variables +//============================================================================ + +//============================================================================ +// helper functions +//============================================================================ + +//+++++ stapl.c replacement +int urj_jam_jtag_io (int tms, int tdi, int read_tdo) +{ + (void) tms; + (void) tdi; + (void) read_tdo; + return 0; // JAMC_SUCCESS +} + +int urj_jam_jtag_io_transfer (int count, char *tdi, char *tdo) +{ + (void) count; + (void) tdi; + (void) tdo; + return 0; // JAMC_SUCCESS +} +void urj_jam_flush_and_delay (int32_t microseconds) +{ + (void) microseconds; +} +int urj_jam_seek (int32_t offset) +{ + (void) offset; + return 0; +} +int urj_jam_getc (void) +{ + return 0; +} +void urj_jam_message (const char *message_text) +{ + printf("%s(%s)\n", __func__, message_text); +} +void urj_jam_export_integer (const char *key, int32_t value) +{ + (void) key; + (void) value; +} +void urj_jam_export_boolean_array ( + char *key, unsigned char *data, int32_t count) +{ + (void) key; + (void) data; + (void) count; +} +//+++++ end stapl.c replacement + +#define STR_INTLR(t) [t] = #t +static const char * typeStr(JAME_EXPRESSION_TYPE type) +{ + static char badType[20]; + static const char * typeAry[JAM_EXPR_MAX] = { + STR_INTLR(JAM_ILLEGAL_EXPR_TYPE), + STR_INTLR(JAM_INTEGER_EXPR), + STR_INTLR(JAM_BOOLEAN_EXPR), + STR_INTLR(JAM_INT_OR_BOOL_EXPR), + STR_INTLR(JAM_ARRAY_REFERENCE), + }; + if (type < JAM_EXPR_MAX) + { + return typeAry[type]; + } + else + { + snprintf(badType, 20, "BAD type %d", type); + return badType; + } +} +static const char * retStr(JAM_RETURN_TYPE ret) +{ + static char badRet[20]; + static const char * retAry[25] = { + STR_INTLR(JAMC_SUCCESS), + STR_INTLR(JAMC_OUT_OF_MEMORY), + STR_INTLR(JAMC_IO_ERROR), + STR_INTLR(JAMC_SYNTAX_ERROR), + STR_INTLR(JAMC_UNEXPECTED_END), + STR_INTLR(JAMC_UNDEFINED_SYMBOL), + STR_INTLR(JAMC_REDEFINED_SYMBOL), + STR_INTLR(JAMC_INTEGER_OVERFLOW), + STR_INTLR(JAMC_DIVIDE_BY_ZERO), + STR_INTLR(JAMC_CRC_ERROR), + STR_INTLR(JAMC_INTERNAL_ERROR), + STR_INTLR(JAMC_BOUNDS_ERROR), + STR_INTLR(JAMC_TYPE_MISMATCH), + STR_INTLR(JAMC_ASSIGN_TO_CONST), + STR_INTLR(JAMC_NEXT_UNEXPECTED), + STR_INTLR(JAMC_POP_UNEXPECTED), + STR_INTLR(JAMC_RETURN_UNEXPECTED), + STR_INTLR(JAMC_ILLEGAL_SYMBOL), + STR_INTLR(JAMC_VECTOR_MAP_FAILED), + STR_INTLR(JAMC_USER_ABORT), + STR_INTLR(JAMC_STACK_OVERFLOW), + STR_INTLR(JAMC_ILLEGAL_OPCODE), + STR_INTLR(JAMC_PHASE_ERROR), + STR_INTLR(JAMC_SCOPE_ERROR), + STR_INTLR(JAMC_ACTION_NOT_FOUND), + }; + if (ret <= JAMC_ACTION_NOT_FOUND) + { + return retAry[ret]; + } + else + { + snprintf(badRet, 20, "BAD ret %d", ret); + return badRet; + } +} +//============================================================================ +// Test code +//============================================================================ +static char *statement_buffer = NULL; +static void check_init_symtab_stack(void) +{ + //+++++ urj_jam_execute replacement + JAM_RETURN_TYPE status = JAMC_SUCCESS; + status = urj_jam_init_symbol_table (); + + if (status == JAMC_SUCCESS) + { + status = urj_jam_init_stack (); + } + + if (status == JAMC_SUCCESS) + { + status = urj_jam_init_jtag (); + } + + if (status == JAMC_SUCCESS) + { + status = urj_jam_init_heap (); + } + + if (status == JAMC_SUCCESS) + { + status = urj_jam_seek (0L); + } + + if (status == JAMC_SUCCESS) + { + statement_buffer = malloc (JAMC_MAX_STATEMENT_LENGTH + 1024); + + if (statement_buffer == NULL) + { + status = JAMC_OUT_OF_MEMORY; + } + } + //+++++ end urj_jam_execute replacement + is_int(status, JAMC_SUCCESS, "urj_jam_execute inits are JAMC_SUCCESS"); + + for (int i = 0; i < INITSYMARY_NRELM; ++i) + { + const struct sInitSym *const pIS = &InitSymAry[i]; + JAM_RETURN_TYPE res = urj_jam_add_symbol( + pIS->type, pIS->name, pIS->value, (int32_t) i * 10); + is_int(res, JAMC_SUCCESS, + "urj_jam_add_symbol(\"%s\") is JAMC_SUCCESS", pIS->name); + } +} + +void check__urj_jam_evaluate_expression(void) +{ + check_init_symtab_stack(); + for (int i = 0; i < EVAL_EXP_NRELM; ++ i) + { + const struct sEvalExpSpec *const pS = &EvalSpecAry[i]; + diag("[%d] urj_jam_evaluate_expression(\"%s\")", i, pS->expr); + + int32_t result = 0xDEADBEEF; + JAME_EXPRESSION_TYPE result_type = JAM_EXPR_MAX; + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + JAM_RETURN_TYPE res + = urj_jam_evaluate_expression( + (char *) pS->expr, // removing const is OK + &result, &result_type); + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + is_int(res, pS->ret_x, " return value is %s", retStr(pS->ret_x)); + if (pS->ret_x == JAMC_SUCCESS) + { + is_int(result_type, pS->typ_x, + " result_type is %s", + typeStr(pS->typ_x)); + is_int(result, pS->res_x, " result is %d", pS->res_x); + } + } +} diff --git a/urjtag/tests/stapl/jamexp_shrd.h b/urjtag/tests/stapl/jamexp_shrd.h new file mode 100644 index 00000000..6d66e79b --- /dev/null +++ b/urjtag/tests/stapl/jamexp_shrd.h @@ -0,0 +1,45 @@ +/** + * \author SPDX-FileCopyrightText: 2022 Peter Poeschl <pp+...@ne...> + * + * \copyright SPDX-License-Identifier: GPL-2.0-or-later + * + * \file jamexp_shrd.h + * \brief Common test function to check urj_jam_evaluate_expression() results. + */ + +#ifndef JAMEXP_SHRD_H +#define JAMEXP_SHRD_H + +/// Number of elements in InitSymAry. +#define INITSYMARY_NRELM 12 +/// Number of tests in check_init_symtab_stack(). +#define CHECK_INIT_SYMTAB_STACK \ + (0 \ + + 1 \ + + INITSYMARY_NRELM \ + ) +/// Number of EvalSpecAry elements with expected .ret_x == JAMC_SUCCESS, +#define EVAL_EXP_NRELM_GOOD 164 +/// Number of EvalSpecAry elements with expected .ret_x != JAMC_SUCCESS. +#define EVAL_EXP_NRELM_BAD 61 +/// Number of EvalSpecAry elements +#define EVAL_EXP_NRELM (EVAL_EXP_NRELM_GOOD + EVAL_EXP_NRELM_BAD) +/// Number of tests in EvalSpecAry element with .ret_x == JAMC_SUCCESS. +#define EVAL_EXP_NRCHK_GOOD 3 +/// Number of tests in EvalSpecAry element with .ret_x != JAMC_SUCCESS. +#define EVAL_EXP_NRCHK_BAD 1 +/// Number of tzests in check__urj_jam_evaluate_expression(). +#define CHECK__URJ_JAM_EVALUATE_EXPRESSION \ + ( 0 \ + + (EVAL_EXP_NRELM_GOOD * EVAL_EXP_NRCHK_GOOD) \ + + (EVAL_EXP_NRELM_BAD * EVAL_EXP_NRCHK_BAD) \ + ) +/// Number of planned tests. +#define PLAN_TESTS \ + ( 0 \ + + CHECK_INIT_SYMTAB_STACK \ + + CHECK__URJ_JAM_EVALUATE_EXPRESSION \ + ) + +extern void check__urj_jam_evaluate_expression(void); +#endif // JAMEXP_SHRD_H -- 2.35.1 |
From: Peter P. <pp+...@ne...> - 2022-08-13 13:25:58
|
Files from commit 14801bbe866e from 2022-02-06 copied to this project according to 'USING THE HARNESS' in https://www.eyrie.org/~eagle/software/c-tap-harness/readme.html Signed-off-by: Peter Pöschl <pp+...@ne...> --- urjtag/tests/tap/basic.c | 1029 +++++++++++++++++++++++++++++++++++++ urjtag/tests/tap/basic.h | 192 +++++++ urjtag/tests/tap/macros.h | 99 ++++ 3 files changed, 1320 insertions(+) create mode 100644 urjtag/tests/tap/basic.c create mode 100644 urjtag/tests/tap/basic.h create mode 100644 urjtag/tests/tap/macros.h diff --git a/urjtag/tests/tap/basic.c b/urjtag/tests/tap/basic.c new file mode 100644 index 00000000..8f44f15d --- /dev/null +++ b/urjtag/tests/tap/basic.c @@ -0,0 +1,1029 @@ +/* + * Some utility routines for writing tests. + * + * Here are a variety of utility routines for writing tests compatible with + * the TAP protocol. All routines of the form ok() or is*() take a test + * number and some number of appropriate arguments, check to be sure the + * results match the expected output using the arguments, and print out + * something appropriate for that test number. Other utility routines help in + * constructing more complex tests, skipping tests, reporting errors, setting + * up the TAP output format, or finding things in the test environment. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Written by Russ Allbery <ea...@ey...> + * Copyright 2009-2019, 2021 Russ Allbery <ea...@ey...> + * Copyright 2001-2002, 2004-2008, 2011-2014 + * The Board of Trustees of the Leland Stanford Junior University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ + +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef _WIN32 +# include <direct.h> +#else +# include <sys/stat.h> +#endif +#include <sys/types.h> +#include <unistd.h> + +#include <tests/tap/basic.h> + +/* Windows provides mkdir and rmdir under different names. */ +#ifdef _WIN32 +# define mkdir(p, m) _mkdir(p) +# define rmdir(p) _rmdir(p) +#endif + +/* + * The test count. Always contains the number that will be used for the next + * test status. This is exported to callers of the library. + */ +unsigned long testnum = 1; + +/* + * Status information stored so that we can give a test summary at the end of + * the test case. We store the planned final test and the count of failures. + * We can get the highest test count from testnum. + */ +static unsigned long _planned = 0; +static unsigned long _failed = 0; + +/* + * Store the PID of the process that called plan() and only summarize + * results when that process exits, so as to not misreport results in forked + * processes. + */ +static pid_t _process = 0; + +/* + * If true, we're doing lazy planning and will print out the plan based on the + * last test number at the end of testing. + */ +static int _lazy = 0; + +/* + * If true, the test was aborted by calling bail(). Currently, this is only + * used to ensure that we pass a false value to any cleanup functions even if + * all tests to that point have passed. + */ +static int _aborted = 0; + +/* + * Registered cleanup functions. These are stored as a linked list and run in + * registered order by finish when the test program exits. Each function is + * passed a boolean value indicating whether all tests were successful. + */ +struct cleanup_func { + test_cleanup_func func; + test_cleanup_func_with_data func_with_data; + void *data; + struct cleanup_func *next; +}; +static struct cleanup_func *cleanup_funcs = NULL; + +/* + * Registered diag files. Any output found in these files will be printed out + * as if it were passed to diag() before any other output we do. This allows + * background processes to log to a file and have that output interleaved with + * the test output. + */ +struct diag_file { + char *name; + FILE *file; + char *buffer; + size_t bufsize; + struct diag_file *next; +}; +static struct diag_file *diag_files = NULL; + +/* + * Print a specified prefix and then the test description. Handles turning + * the argument list into a va_args structure suitable for passing to + * print_desc, which has to be done in a macro. Assumes that format is the + * argument immediately before the variadic arguments. + */ +#define PRINT_DESC(prefix, format) \ + do { \ + if (format != NULL) { \ + va_list args; \ + printf("%s", prefix); \ + va_start(args, format); \ + vprintf(format, args); \ + va_end(args); \ + } \ + } while (0) + + +/* + * Form a new string by concatenating multiple strings. The arguments must be + * terminated by (const char *) 0. + * + * This function only exists because we can't assume asprintf. We can't + * simulate asprintf with snprintf because we're only assuming SUSv3, which + * does not require that snprintf with a NULL buffer return the required + * length. When those constraints are relaxed, this should be ripped out and + * replaced with asprintf or a more trivial replacement with snprintf. + */ +static char * +concat(const char *first, ...) +{ + va_list args; + char *result; + const char *string; + size_t offset; + size_t length = 0; + + /* + * Find the total memory required. Ensure we don't overflow length. See + * the comment for breallocarray for why we're using UINT_MAX here. + */ + va_start(args, first); + for (string = first; string != NULL; string = va_arg(args, const char *)) { + if (length >= UINT_MAX - strlen(string)) + bail("strings too long in concat"); + length += strlen(string); + } + va_end(args); + length++; + + /* Create the string. */ + result = bcalloc_type(length, char); + va_start(args, first); + offset = 0; + for (string = first; string != NULL; string = va_arg(args, const char *)) { + memcpy(result + offset, string, strlen(string)); + offset += strlen(string); + } + va_end(args); + result[offset] = '\0'; + return result; +} + + +/* + * Helper function for check_diag_files to handle a single line in a diag + * file. + * + * The general scheme here used is as follows: read one line of output. If we + * get NULL, check for an error. If there was one, bail out of the test + * program; otherwise, return, and the enclosing loop will check for EOF. + * + * If we get some data, see if it ends in a newline. If it doesn't end in a + * newline, we have one of two cases: our buffer isn't large enough, in which + * case we resize it and try again, or we have incomplete data in the file, in + * which case we rewind the file and will try again next time. + * + * Returns a boolean indicating whether the last line was incomplete. + */ +static int +handle_diag_file_line(struct diag_file *file, fpos_t where) +{ + int size; + size_t length; + + /* Read the next line from the file. */ + size = file->bufsize > INT_MAX ? INT_MAX : (int) file->bufsize; + if (fgets(file->buffer, size, file->file) == NULL) { + if (ferror(file->file)) + sysbail("cannot read from %s", file->name); + return 0; + } + + /* + * See if the line ends in a newline. If not, see which error case we + * have. + */ + length = strlen(file->buffer); + if (file->buffer[length - 1] != '\n') { + int incomplete = 0; + + /* Check whether we ran out of buffer space and resize if so. */ + if (length < file->bufsize - 1) + incomplete = 1; + else { + file->bufsize += BUFSIZ; + file->buffer = + breallocarray_type(file->buffer, file->bufsize, char); + } + + /* + * On either incomplete lines or too small of a buffer, rewind + * and read the file again (on the next pass, if incomplete). + * It's simpler than trying to double-buffer the file. + */ + if (fsetpos(file->file, &where) < 0) + sysbail("cannot set position in %s", file->name); + return incomplete; + } + + /* We saw a complete line. Print it out. */ + printf("# %s", file->buffer); + return 0; +} + + +/* + * Check all registered diag_files for any output. We only print out the + * output if we see a complete line; otherwise, we wait for the next newline. + */ +static void +check_diag_files(void) +{ + struct diag_file *file; + fpos_t where; + int incomplete; + + /* + * Walk through each file and read each line of output available. + */ + for (file = diag_files; file != NULL; file = file->next) { + clearerr(file->file); + + /* Store the current position in case we have to rewind. */ + if (fgetpos(file->file, &where) < 0) + sysbail("cannot get position in %s", file->name); + + /* Continue until we get EOF or an incomplete line of data. */ + incomplete = 0; + while (!feof(file->file) && !incomplete) { + incomplete = handle_diag_file_line(file, where); + } + } +} + + +/* + * Our exit handler. Called on completion of the test to report a summary of + * results provided we're still in the original process. This also handles + * printing out the plan if we used plan_lazy(), although that's suppressed if + * we never ran a test (due to an early bail, for example), and running any + * registered cleanup functions. + */ +static void +finish(void) +{ + int success, primary; + struct cleanup_func *current; + unsigned long highest = testnum - 1; + struct diag_file *file, *tmp; + + /* Check for pending diag_file output. */ + check_diag_files(); + + /* Free the diag_files. */ + file = diag_files; + while (file != NULL) { + tmp = file; + file = file->next; + fclose(tmp->file); + free(tmp->name); + free(tmp->buffer); + free(tmp); + } + diag_files = NULL; + + /* + * Determine whether all tests were successful, which is needed before + * calling cleanup functions since we pass that fact to the functions. + */ + if (_planned == 0 && _lazy) + _planned = highest; + success = (!_aborted && _planned == highest && _failed == 0); + + /* + * If there are any registered cleanup functions, we run those first. We + * always run them, even if we didn't run a test. Don't do anything + * except free the diag_files and call cleanup functions if we aren't the + * primary process (the process in which plan or plan_lazy was called), + * and tell the cleanup functions that fact. + */ + primary = (_process == 0 || getpid() == _process); + while (cleanup_funcs != NULL) { + if (cleanup_funcs->func_with_data) { + void *data = cleanup_funcs->data; + + cleanup_funcs->func_with_data(success, primary, data); + } else { + cleanup_funcs->func(success, primary); + } + current = cleanup_funcs; + cleanup_funcs = cleanup_funcs->next; + free(current); + } + if (!primary) + return; + + /* Don't do anything further if we never planned a test. */ + if (_planned == 0) + return; + + /* If we're aborting due to bail, don't print summaries. */ + if (_aborted) + return; + + /* Print out the lazy plan if needed. */ + fflush(stderr); + if (_lazy) + printf("1..%lu\n", _planned); + + /* Print out a summary of the results. */ + if (_planned > highest) + diag("Looks like you planned %lu test%s but only ran %lu", _planned, + (_planned > 1 ? "s" : ""), highest); + else if (_planned < highest) + diag("Looks like you planned %lu test%s but ran %lu extra", _planned, + (_planned > 1 ? "s" : ""), highest - _planned); + else if (_failed > 0) + diag("Looks like you failed %lu test%s of %lu", _failed, + (_failed > 1 ? "s" : ""), _planned); + else if (_planned != 1) + diag("All %lu tests successful or skipped", _planned); + else + diag("%lu test successful or skipped", _planned); +} + + +/* + * Initialize things. Turns on line buffering on stdout and then prints out + * the number of tests in the test suite. We intentionally don't check for + * pending diag_file output here, since it should really come after the plan. + */ +void +plan(unsigned long count) +{ + if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0) + sysdiag("cannot set stdout to line buffered"); + fflush(stderr); + printf("1..%lu\n", count); + testnum = 1; + _planned = count; + _process = getpid(); + if (atexit(finish) != 0) { + sysdiag("cannot register exit handler"); + diag("cleanups will not be run"); + } +} + + +/* + * Initialize things for lazy planning, where we'll automatically print out a + * plan at the end of the program. Turns on line buffering on stdout as well. + */ +void +plan_lazy(void) +{ + if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0) + sysdiag("cannot set stdout to line buffered"); + testnum = 1; + _process = getpid(); + _lazy = 1; + if (atexit(finish) != 0) + sysbail("cannot register exit handler to display plan"); +} + + +/* + * Skip the entire test suite and exits. Should be called instead of plan(), + * not after it, since it prints out a special plan line. Ignore diag_file + * output here, since it's not clear if it's allowed before the plan. + */ +void +skip_all(const char *format, ...) +{ + fflush(stderr); + printf("1..0 # skip"); + PRINT_DESC(" ", format); + putchar('\n'); + exit(0); +} + + +/* + * Takes a boolean success value and assumes the test passes if that value + * is true and fails if that value is false. + */ +int +ok(int success, const char *format, ...) +{ + fflush(stderr); + check_diag_files(); + printf("%sok %lu", success ? "" : "not ", testnum++); + if (!success) + _failed++; + PRINT_DESC(" - ", format); + putchar('\n'); + return success; +} + + +/* + * Same as ok(), but takes the format arguments as a va_list. + */ +int +okv(int success, const char *format, va_list args) +{ + fflush(stderr); + check_diag_files(); + printf("%sok %lu", success ? "" : "not ", testnum++); + if (!success) + _failed++; + if (format != NULL) { + printf(" - "); + vprintf(format, args); + } + putchar('\n'); + return success; +} + + +/* + * Skip a test. + */ +void +skip(const char *reason, ...) +{ + fflush(stderr); + check_diag_files(); + printf("ok %lu # skip", testnum++); + PRINT_DESC(" ", reason); + putchar('\n'); +} + + +/* + * Report the same status on the next count tests. + */ +int +ok_block(unsigned long count, int success, const char *format, ...) +{ + unsigned long i; + + fflush(stderr); + check_diag_files(); + for (i = 0; i < count; i++) { + printf("%sok %lu", success ? "" : "not ", testnum++); + if (!success) + _failed++; + PRINT_DESC(" - ", format); + putchar('\n'); + } + return success; +} + + +/* + * Skip the next count tests. + */ +void +skip_block(unsigned long count, const char *reason, ...) +{ + unsigned long i; + + fflush(stderr); + check_diag_files(); + for (i = 0; i < count; i++) { + printf("ok %lu # skip", testnum++); + PRINT_DESC(" ", reason); + putchar('\n'); + } +} + + +/* + * Takes two boolean values and requires the truth value of both match. + */ +int +is_bool(int left, int right, const char *format, ...) +{ + int success; + + fflush(stderr); + check_diag_files(); + success = (!!left == !!right); + if (success) + printf("ok %lu", testnum++); + else { + diag(" left: %s", !!left ? "true" : "false"); + diag("right: %s", !!right ? "true" : "false"); + printf("not ok %lu", testnum++); + _failed++; + } + PRINT_DESC(" - ", format); + putchar('\n'); + return success; +} + + +/* + * Takes two integer values and requires they match. + */ +int +is_int(long left, long right, const char *format, ...) +{ + int success; + + fflush(stderr); + check_diag_files(); + success = (left == right); + if (success) + printf("ok %lu", testnum++); + else { + diag(" left: %ld", left); + diag("right: %ld", right); + printf("not ok %lu", testnum++); + _failed++; + } + PRINT_DESC(" - ", format); + putchar('\n'); + return success; +} + + +/* + * Takes two strings and requires they match (using strcmp). NULL arguments + * are permitted and handled correctly. + */ +int +is_string(const char *left, const char *right, const char *format, ...) +{ + int success; + + fflush(stderr); + check_diag_files(); + + /* Compare the strings, being careful of NULL. */ + if (left == NULL) + success = (right == NULL); + else if (right == NULL) + success = 0; + else + success = (strcmp(left, right) == 0); + + /* Report the results. */ + if (success) + printf("ok %lu", testnum++); + else { + diag(" left: %s", left == NULL ? "(null)" : left); + diag("right: %s", right == NULL ? "(null)" : right); + printf("not ok %lu", testnum++); + _failed++; + } + PRINT_DESC(" - ", format); + putchar('\n'); + return success; +} + + +/* + * Takes two unsigned longs and requires they match. On failure, reports them + * in hex. + */ +int +is_hex(unsigned long left, unsigned long right, const char *format, ...) +{ + int success; + + fflush(stderr); + check_diag_files(); + success = (left == right); + if (success) + printf("ok %lu", testnum++); + else { + diag(" left: %lx", (unsigned long) left); + diag("right: %lx", (unsigned long) right); + printf("not ok %lu", testnum++); + _failed++; + } + PRINT_DESC(" - ", format); + putchar('\n'); + return success; +} + + +/* + * Takes pointers to a regions of memory and requires that len bytes from each + * match. Otherwise reports any bytes which didn't match. + */ +int +is_blob(const void *left, const void *right, size_t len, const char *format, + ...) +{ + int success; + size_t i; + + fflush(stderr); + check_diag_files(); + success = (memcmp(left, right, len) == 0); + if (success) + printf("ok %lu", testnum++); + else { + const unsigned char *left_c = (const unsigned char *) left; + const unsigned char *right_c = (const unsigned char *) right; + + for (i = 0; i < len; i++) { + if (left_c[i] != right_c[i]) + diag("offset %lu: left %02x, right %02x", (unsigned long) i, + left_c[i], right_c[i]); + } + printf("not ok %lu", testnum++); + _failed++; + } + PRINT_DESC(" - ", format); + putchar('\n'); + return success; +} + + +/* + * Bail out with an error. + */ +void +bail(const char *format, ...) +{ + va_list args; + + _aborted = 1; + fflush(stderr); + check_diag_files(); + fflush(stdout); + printf("Bail out! "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); + exit(255); +} + + +/* + * Bail out with an error, appending strerror(errno). + */ +void +sysbail(const char *format, ...) +{ + va_list args; + int oerrno = errno; + + _aborted = 1; + fflush(stderr); + check_diag_files(); + fflush(stdout); + printf("Bail out! "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf(": %s\n", strerror(oerrno)); + exit(255); +} + + +/* + * Report a diagnostic to stderr. Always returns 1 to allow embedding in + * compound statements. + */ +int +diag(const char *format, ...) +{ + va_list args; + + fflush(stderr); + check_diag_files(); + fflush(stdout); + printf("# "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); + return 1; +} + + +/* + * Report a diagnostic to stderr, appending strerror(errno). Always returns 1 + * to allow embedding in compound statements. + */ +int +sysdiag(const char *format, ...) +{ + va_list args; + int oerrno = errno; + + fflush(stderr); + check_diag_files(); + fflush(stdout); + printf("# "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf(": %s\n", strerror(oerrno)); + return 1; +} + + +/* + * Register a new file for diag_file processing. + */ +void +diag_file_add(const char *name) +{ + struct diag_file *file, *prev; + + file = bcalloc_type(1, struct diag_file); + file->name = bstrdup(name); + file->file = fopen(file->name, "r"); + if (file->file == NULL) + sysbail("cannot open %s", name); + file->buffer = bcalloc_type(BUFSIZ, char); + file->bufsize = BUFSIZ; + if (diag_files == NULL) + diag_files = file; + else { + for (prev = diag_files; prev->next != NULL; prev = prev->next) + ; + prev->next = file; + } +} + + +/* + * Remove a file from diag_file processing. If the file is not found, do + * nothing, since there are some situations where it can be removed twice + * (such as if it's removed from a cleanup function, since cleanup functions + * are called after freeing all the diag_files). + */ +void +diag_file_remove(const char *name) +{ + struct diag_file *file; + struct diag_file **prev = &diag_files; + + for (file = diag_files; file != NULL; file = file->next) { + if (strcmp(file->name, name) == 0) { + *prev = file->next; + fclose(file->file); + free(file->name); + free(file->buffer); + free(file); + return; + } + prev = &file->next; + } +} + + +/* + * Allocate cleared memory, reporting a fatal error with bail on failure. + */ +void * +bcalloc(size_t n, size_t size) +{ + void *p; + + p = calloc(n, size); + if (p == NULL) + sysbail("failed to calloc %lu", (unsigned long) (n * size)); + return p; +} + + +/* + * Allocate memory, reporting a fatal error with bail on failure. + */ +void * +bmalloc(size_t size) +{ + void *p; + + p = malloc(size); + if (p == NULL) + sysbail("failed to malloc %lu", (unsigned long) size); + return p; +} + + +/* + * Reallocate memory, reporting a fatal error with bail on failure. + */ +void * +brealloc(void *p, size_t size) +{ + p = realloc(p, size); + if (p == NULL) + sysbail("failed to realloc %lu bytes", (unsigned long) size); + return p; +} + + +/* + * The same as brealloc, but determine the size by multiplying an element + * count by a size, similar to calloc. The multiplication is checked for + * integer overflow. + * + * We should technically use SIZE_MAX here for the overflow check, but + * SIZE_MAX is C99 and we're only assuming C89 + SUSv3, which does not + * guarantee that it exists. They do guarantee that UINT_MAX exists, and we + * can assume that UINT_MAX <= SIZE_MAX. + * + * (In theory, C89 and C99 permit size_t to be smaller than unsigned int, but + * I disbelieve in the existence of such systems and they will have to cope + * without overflow checks.) + */ +void * +breallocarray(void *p, size_t n, size_t size) +{ + if (n > 0 && UINT_MAX / n <= size) + bail("reallocarray too large"); + if (n == 0) + n = 1; + p = realloc(p, n * size); + if (p == NULL) + sysbail("failed to realloc %lu bytes", (unsigned long) (n * size)); + return p; +} + + +/* + * Copy a string, reporting a fatal error with bail on failure. + */ +char * +bstrdup(const char *s) +{ + char *p; + size_t len; + + len = strlen(s) + 1; + p = (char *) malloc(len); + if (p == NULL) + sysbail("failed to strdup %lu bytes", (unsigned long) len); + memcpy(p, s, len); + return p; +} + + +/* + * Copy up to n characters of a string, reporting a fatal error with bail on + * failure. Don't use the system strndup function, since it may not exist and + * the TAP library doesn't assume any portability support. + */ +char * +bstrndup(const char *s, size_t n) +{ + const char *p; + char *copy; + size_t length; + + /* Don't assume that the source string is nul-terminated. */ + for (p = s; (size_t) (p - s) < n && *p != '\0'; p++) + ; + length = (size_t) (p - s); + copy = (char *) malloc(length + 1); + if (copy == NULL) + sysbail("failed to strndup %lu bytes", (unsigned long) length); + memcpy(copy, s, length); + copy[length] = '\0'; + return copy; +} + + +/* + * Locate a test file. Given the partial path to a file, look under + * C_TAP_BUILD and then C_TAP_SOURCE for the file and return the full path to + * the file. Returns NULL if the file doesn't exist. A non-NULL return + * should be freed with test_file_path_free(). + */ +char * +test_file_path(const char *file) +{ + char *base; + char *path = NULL; + const char *envs[] = {"C_TAP_BUILD", "C_TAP_SOURCE", NULL}; + int i; + + for (i = 0; envs[i] != NULL; i++) { + base = getenv(envs[i]); + if (base == NULL) + continue; + path = concat(base, "/", file, (const char *) 0); + if (access(path, R_OK) == 0) + break; + free(path); + path = NULL; + } + return path; +} + + +/* + * Free a path returned from test_file_path(). This function exists primarily + * for Windows, where memory must be freed from the same library domain that + * it was allocated from. + */ +void +test_file_path_free(char *path) +{ + free(path); +} + + +/* + * Create a temporary directory, tmp, under C_TAP_BUILD if set and the current + * directory if it does not. Returns the path to the temporary directory in + * newly allocated memory, and calls bail on any failure. The return value + * should be freed with test_tmpdir_free. + * + * This function uses sprintf because it attempts to be independent of all + * other portability layers. The use immediately after a memory allocation + * should be safe without using snprintf or strlcpy/strlcat. + */ +char * +test_tmpdir(void) +{ + const char *build; + char *path = NULL; + + build = getenv("C_TAP_BUILD"); + if (build == NULL) + build = "."; + path = concat(build, "/tmp", (const char *) 0); + if (access(path, X_OK) < 0) + if (mkdir(path, 0777) < 0) + sysbail("error creating temporary directory %s", path); + return path; +} + + +/* + * Free a path returned from test_tmpdir() and attempt to remove the + * directory. If we can't delete the directory, don't worry; something else + * that hasn't yet cleaned up may still be using it. + */ +void +test_tmpdir_free(char *path) +{ + if (path != NULL) + rmdir(path); + free(path); +} + +static void +register_cleanup(test_cleanup_func func, + test_cleanup_func_with_data func_with_data, void *data) +{ + struct cleanup_func *cleanup, **last; + + cleanup = bcalloc_type(1, struct cleanup_func); + cleanup->func = func; + cleanup->func_with_data = func_with_data; + cleanup->data = data; + cleanup->next = NULL; + last = &cleanup_funcs; + while (*last != NULL) + last = &(*last)->next; + *last = cleanup; +} + +/* + * Register a cleanup function that is called when testing ends. All such + * registered functions will be run by finish. + */ +void +test_cleanup_register(test_cleanup_func func) +{ + register_cleanup(func, NULL, NULL); +} + +/* + * Same as above, but also allows an opaque pointer to be passed to the cleanup + * function. + */ +void +test_cleanup_register_with_data(test_cleanup_func_with_data func, void *data) +{ + register_cleanup(NULL, func, data); +} diff --git a/urjtag/tests/tap/basic.h b/urjtag/tests/tap/basic.h new file mode 100644 index 00000000..45f15f28 --- /dev/null +++ b/urjtag/tests/tap/basic.h @@ -0,0 +1,192 @@ +/* + * Basic utility routines for the TAP protocol. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Written by Russ Allbery <ea...@ey...> + * Copyright 2009-2019 Russ Allbery <ea...@ey...> + * Copyright 2001-2002, 2004-2008, 2011-2012, 2014 + * The Board of Trustees of the Leland Stanford Junior University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef TAP_BASIC_H +#define TAP_BASIC_H 1 + +#include <stdarg.h> /* va_list */ +#include <stddef.h> /* size_t */ +#include <tests/tap/macros.h> + +/* + * Used for iterating through arrays. ARRAY_SIZE returns the number of + * elements in the array (useful for a < upper bound in a for loop) and + * ARRAY_END returns a pointer to the element past the end (ISO C99 makes it + * legal to refer to such a pointer as long as it's never dereferenced). + */ +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +#define ARRAY_END(array) (&(array)[ARRAY_SIZE(array)]) + +BEGIN_DECLS + +/* + * The test count. Always contains the number that will be used for the next + * test status. + */ +extern unsigned long testnum; + +/* Print out the number of tests and set standard output to line buffered. */ +void plan(unsigned long count); + +/* + * Prepare for lazy planning, in which the plan will be printed automatically + * at the end of the test program. + */ +void plan_lazy(void); + +/* Skip the entire test suite. Call instead of plan. */ +void skip_all(const char *format, ...) + __attribute__((__noreturn__, __format__(printf, 1, 2))); + +/* + * Basic reporting functions. The okv() function is the same as ok() but + * takes the test description as a va_list to make it easier to reuse the + * reporting infrastructure when writing new tests. ok() and okv() return the + * value of the success argument. + */ +int ok(int success, const char *format, ...) + __attribute__((__format__(printf, 2, 3))); +int okv(int success, const char *format, va_list args) + __attribute__((__format__(printf, 2, 0))); +void skip(const char *reason, ...) __attribute__((__format__(printf, 1, 2))); + +/* + * Report the same status on, or skip, the next count tests. ok_block() + * returns the value of the success argument. + */ +int ok_block(unsigned long count, int success, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +void skip_block(unsigned long count, const char *reason, ...) + __attribute__((__format__(printf, 2, 3))); + +/* + * Compare two values. Returns true if the test passes and false if it fails. + * is_bool takes an int since the bool type isn't fully portable yet, but + * interprets both arguments for their truth value, not for their numeric + * value. + */ +int is_bool(int, int, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +int is_int(long, long, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +int is_string(const char *, const char *, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +int is_hex(unsigned long, unsigned long, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +int is_blob(const void *, const void *, size_t, const char *format, ...) + __attribute__((__format__(printf, 4, 5))); + +/* Bail out with an error. sysbail appends strerror(errno). */ +void bail(const char *format, ...) + __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2))); +void sysbail(const char *format, ...) + __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2))); + +/* Report a diagnostic to stderr prefixed with #. */ +int diag(const char *format, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +int sysdiag(const char *format, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); + +/* + * Register or unregister a file that contains supplementary diagnostics. + * Before any other output, all registered files will be read, line by line, + * and each line will be reported as a diagnostic as if it were passed to + * diag(). Nul characters are not supported in these files and will result in + * truncated output. + */ +void diag_file_add(const char *file) __attribute__((__nonnull__)); +void diag_file_remove(const char *file) __attribute__((__nonnull__)); + +/* Allocate memory, reporting a fatal error with bail on failure. */ +void *bcalloc(size_t, size_t) + __attribute__((__alloc_size__(1, 2), __malloc__, __warn_unused_result__)); +void *bmalloc(size_t) + __attribute__((__alloc_size__(1), __malloc__, __warn_unused_result__)); +void *breallocarray(void *, size_t, size_t) + __attribute__((__alloc_size__(2, 3), __malloc__, __warn_unused_result__)); +void *brealloc(void *, size_t) + __attribute__((__alloc_size__(2), __malloc__, __warn_unused_result__)); +char *bstrdup(const char *) + __attribute__((__malloc__, __nonnull__, __warn_unused_result__)); +char *bstrndup(const char *, size_t) + __attribute__((__malloc__, __nonnull__, __warn_unused_result__)); + +/* + * Macros that cast the return value from b* memory functions, making them + * usable in C++ code and providing some additional type safety. + */ +#define bcalloc_type(n, type) ((type *) bcalloc((n), sizeof(type))) +#define breallocarray_type(p, n, type) \ + ((type *) breallocarray((p), (n), sizeof(type))) + +/* + * Find a test file under C_TAP_BUILD or C_TAP_SOURCE, returning the full + * path. The returned path should be freed with test_file_path_free(). + */ +char *test_file_path(const char *file) + __attribute__((__malloc__, __nonnull__, __warn_unused_result__)); +void test_file_path_free(char *path); + +/* + * Create a temporary directory relative to C_TAP_BUILD and return the path. + * The returned path should be freed with test_tmpdir_free(). + */ +char *test_tmpdir(void) __attribute__((__malloc__, __warn_unused_result__)); +void test_tmpdir_free(char *path); + +/* + * Register a cleanup function that is called when testing ends. All such + * registered functions will be run during atexit handling (and are therefore + * subject to all the same constraints and caveats as atexit functions). + * + * The function must return void and will be passed two arguments: an int that + * will be true if the test completed successfully and false otherwise, and an + * int that will be true if the cleanup function is run in the primary process + * (the one that called plan or plan_lazy) and false otherwise. If + * test_cleanup_register_with_data is used instead, a generic pointer can be + * provided and will be passed to the cleanup function as a third argument. + * + * test_cleanup_register_with_data is the better API and should have been the + * only API. test_cleanup_register was an API error preserved for backward + * cmpatibility. + */ +typedef void (*test_cleanup_func)(int, int); +typedef void (*test_cleanup_func_with_data)(int, int, void *); + +void test_cleanup_register(test_cleanup_func) __attribute__((__nonnull__)); +void test_cleanup_register_with_data(test_cleanup_func_with_data, void *) + __attribute__((__nonnull__)); + +END_DECLS + +#endif /* TAP_BASIC_H */ diff --git a/urjtag/tests/tap/macros.h b/urjtag/tests/tap/macros.h new file mode 100644 index 00000000..c2c8b5c7 --- /dev/null +++ b/urjtag/tests/tap/macros.h @@ -0,0 +1,99 @@ +/* + * Helpful macros for TAP header files. + * + * This is not, strictly speaking, related to TAP, but any TAP add-on is + * probably going to need these macros, so define them in one place so that + * everyone can pull them in. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2008, 2012-2013, 2015 Russ Allbery <ea...@ey...> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef TAP_MACROS_H +#define TAP_MACROS_H 1 + +/* + * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7 + * could you use the __format__ form of the attributes, which is what we use + * (to avoid confusion with other macros), and only with gcc 2.96 can you use + * the attribute __malloc__. 2.96 is very old, so don't bother trying to get + * the other attributes to work with GCC versions between 2.7 and 2.96. + */ +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) +# define __attribute__(spec) /* empty */ +# endif +#endif + +/* + * We use __alloc_size__, but it was only available in fairly recent versions + * of GCC. Suppress warnings about the unknown attribute if GCC is too old. + * We know that we're GCC at this point, so we can use the GCC variadic macro + * extension, which will still work with versions of GCC too old to have C99 + * variadic macro support. + */ +#if !defined(__attribute__) && !defined(__alloc_size__) +# if defined(__GNUC__) && !defined(__clang__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define __alloc_size__(spec, args...) /* empty */ +# endif +# endif +#endif + +/* Suppress __warn_unused_result__ if gcc is too old. */ +#if !defined(__attribute__) && !defined(__warn_unused_result__) +# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) +# define __warn_unused_result__ /* empty */ +# endif +#endif + +/* + * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ + * settings that GCC does. For them, suppress warnings about unknown + * attributes on declarations. This unfortunately will affect the entire + * compilation context, but there's no push and pop available. + */ +#if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__)) +# pragma GCC diagnostic ignored "-Wattributes" +#endif + +/* Used for unused parameters to silence gcc warnings. */ +#define UNUSED __attribute__((__unused__)) + +/* + * BEGIN_DECLS is used at the beginning of declarations so that C++ + * compilers don't mangle their names. END_DECLS is used at the end. + */ +#undef BEGIN_DECLS +#undef END_DECLS +#ifdef __cplusplus +# define BEGIN_DECLS extern "C" { +# define END_DECLS } +#else +# define BEGIN_DECLS /* empty */ +# define END_DECLS /* empty */ +#endif + +#endif /* TAP_MACROS_H */ -- 2.35.1 |
From: Peter P. <pp+...@ne...> - 2022-08-13 13:25:48
|
Reporting is active when URJ_JAM_YYDEBUG is defined Signed-off-by: Peter Pöschl <pp+...@ne...> --- urjtag/src/stapl/jamexp.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/urjtag/src/stapl/jamexp.c b/urjtag/src/stapl/jamexp.c index 5e1f9d92..60a8d8fb 100644 --- a/urjtag/src/stapl/jamexp.c +++ b/urjtag/src/stapl/jamexp.c @@ -15,6 +15,9 @@ #include "jamarray.h" #include "jamutil.h" #include "jamytab.h" +#ifdef URJ_JAM_YYDEBUG +#include <stdio.h> +#endif // URJ_JAM_YYDEBUG /* ------------- LEXER DEFINITIONS -----------------------------------------*/ @@ -1580,6 +1583,17 @@ urj_jam_yyparse (void) if (jam_yychk[jam_yyn = jam_yyact[jam_yyn]] == token) { /* valid shift */ +#ifdef URJ_JAM_YYDEBUG + if (token <= 0xff) + { + printf("# .. shift '%c' -> state %d\n", token, jam_yyn); + } + else + { + // symbols are NOT jam_keyword_table[*].token! + printf("# .. shift %d -> state %d\n", token, jam_yyn); + } +#endif // URJ_JAM_YYDEBUG token = -1; urj_jam_yyval = urj_jam_yylval; jam_yystate = jam_yyn; @@ -1666,6 +1680,14 @@ urj_jam_yyparse (void) if (jam_yyj >= YYLAST || jam_yychk[jam_yystate = jam_yyact[jam_yyj]] != -jam_yyn) jam_yystate = jam_yyact[jam_yypgo[jam_yyn]]; +#ifdef URJ_JAM_YYDEBUG + printf("# .. reduce P%d:", jam_yym); + for (int ri = -jam_yyr2[jam_yym] + 1; ri <= 0; ++ ri) + { + printf(" (t=%d v=%d)", jam_yypvt[ri].type, jam_yypvt[ri].val); + } + printf(" -> sym %d, state %d\n", jam_yyn, jam_yystate); +#endif // URJ_JAM_YYDEBUG switch (jam_yym) { -- 2.35.1 |
From: Ilia P. <in...@il...> - 2022-01-06 14:12:09
|
Hello all, I added two devices into the lattice folder: The MachXO3 and the ECP5 (LFE5U-45F), both footprints are caBGA256, Both are recognized by urJTAG and I am able to program them using the UsbBlaster programmer. I made a merge request on sourceforge. Let me know your thoughts about this addon. Thanks in advance, Ilia Platone |
From: Geert S. <sta...@st...> - 2021-09-29 19:56:52
|
On Thu, Sep 23, 2021 at 10:41:12AM +1000, Benjamin Herrenschmidt wrote: > Currently, we have two cases where we try to "re-use" the urj_cable_driver_t > structure for two different USB variants. This doesnt' actually work however > at least not for > > URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002A, "-mpsse", "ARM-USB-TINY-H", armusbtiny_h) > > Since the name doesn't match the name in the driver. > > To avoid confusion, this just duplicates the structures and keep a 1:1 relationship > between URJ_DECLARE_FTDX_CABLE entries and urj_cable_driver_t structures. > > Signed-off-by: Benjamin Herrenschmidt <be...@ke...> Thanks, applied. Regards Geert Stappers P.S. Sorry for the delay in the response. |
From: Geert S. <sta...@st...> - 2021-09-26 18:26:15
|
On Sun, Sep 26, 2021 at 09:54:22PM +1000, Anton Blanchard wrote: > On Sat, 25 Sep 2021 13:52:07 +1000 > Anton Blanchard <an...@oz...> wrote: > > > The Nexys Video uses the second interface, so we need to set that in > > order to autodetect it correctly. > > I've since tested another Digilent board (Arty A7), and annoyingly it > has exactly the same PID/VID and description, but uses the first > interface. > > I'll resubmit without patches 3 and 4, That allows me to drop the previous patches. > which means the Arty auto > detects and the Nexys Video doesn't. There are almost certainly more > Arty boards out there, considering they are cheaper. > > Thanks, > Anton Groeten Geert Stappers -- Silence is hard to parse |
From: Anton B. <an...@oz...> - 2021-09-26 11:54:39
|
On Sat, 25 Sep 2021 13:52:07 +1000 Anton Blanchard <an...@oz...> wrote: > The Nexys Video uses the second interface, so we need to set that in > order to autodetect it correctly. I've since tested another Digilent board (Arty A7), and annoyingly it has exactly the same PID/VID and description, but uses the first interface. I'll resubmit without patches 3 and 4, which means the Arty auto detects and the Nexys Video doesn't. There are almost certainly more Arty boards out there, considering they are cheaper. Thanks, Anton |
From: Anton B. <an...@oz...> - 2021-09-25 04:17:23
|
We need to be able to differentiate between USB devices with the same PID/VID, so add a way to set the desc field. --- urjtag/src/tap/cable/dirtyjtag.c | 2 +- urjtag/src/tap/cable/ft2232.c | 42 +++++++++++++------------- urjtag/src/tap/cable/generic_usbconn.h | 4 +-- urjtag/src/tap/cable/ice100.c | 4 +-- urjtag/src/tap/cable/jlink.c | 2 +- urjtag/src/tap/cable/usbblaster.c | 8 ++--- urjtag/src/tap/cable/vsllink.c | 2 +- urjtag/src/tap/cable/xpc.c | 4 +-- urjtag/src/tap/usbconn/libftdx.h | 14 ++++----- 9 files changed, 41 insertions(+), 41 deletions(-) diff --git a/urjtag/src/tap/cable/dirtyjtag.c b/urjtag/src/tap/cable/dirtyjtag.c index e93b44fa..94473e09 100644 --- a/urjtag/src/tap/cable/dirtyjtag.c +++ b/urjtag/src/tap/cable/dirtyjtag.c @@ -338,4 +338,4 @@ const urj_cable_driver_t urj_tap_cable_dirtyjtag_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE(0x1209, 0xC0CA, "libusb", "dirtyjtag", dirtyjtag) +URJ_DECLARE_USBCONN_CABLE(0x1209, 0xC0CA, "libusb", "dirtyjtag", dirtyjtag, NULL) diff --git a/urjtag/src/tap/cable/ft2232.c b/urjtag/src/tap/cable/ft2232.c index 5e24090c..0540dbaa 100644 --- a/urjtag/src/tap/cable/ft2232.c +++ b/urjtag/src/tap/cable/ft2232.c @@ -2589,7 +2589,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0000, 0x0000, "-mpsse", "FT2232", ft2232) +URJ_DECLARE_FTDX_CABLE(0x0000, 0x0000, "-mpsse", "FT2232", ft2232, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_armusbocd_driver = { "ARM-USB-OCD", @@ -2609,8 +2609,8 @@ const urj_cable_driver_t urj_tap_cable_ft2232_armusbocd_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0003, "-mpsse", "ARM-USB-OCD", armusbocd) -URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0004, "-mpsse", "ARM-USB-OCD", armusbocdtiny) +URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0003, "-mpsse", "ARM-USB-OCD", armusbocd, NULL) +URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0004, "-mpsse", "ARM-USB-OCD", armusbocdtiny, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_armusbtiny_h_driver = { "ARM-USB-OCD-H", @@ -2630,8 +2630,8 @@ const urj_cable_driver_t urj_tap_cable_ft2232_armusbtiny_h_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002A, "-mpsse", "ARM-USB-TINY-H", armusbtiny_h) -URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002B, "-mpsse", "ARM-USB-OCD-H", armusbocd_h) +URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002A, "-mpsse", "ARM-USB-TINY-H", armusbtiny_h, NULL) +URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002B, "-mpsse", "ARM-USB-OCD-H", armusbocd_h, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_gnice_driver = { "gnICE", @@ -2651,7 +2651,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_gnice_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0456, 0xF000, "-mpsse", "gnICE", gnice) +URJ_DECLARE_FTDX_CABLE(0x0456, 0xF000, "-mpsse", "gnICE", gnice, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_gniceplus_driver = { "gnICE+", @@ -2671,7 +2671,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_gniceplus_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0456, 0xF001, "-mpsse", "gnICE+", gniceplus) +URJ_DECLARE_FTDX_CABLE(0x0456, 0xF001, "-mpsse", "gnICE+", gniceplus, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_jtagkey_driver = { "JTAGkey", @@ -2691,7 +2691,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_jtagkey_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xCFF8, "-mpsse", "JTAGkey", jtagkey) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xCFF8, "-mpsse", "JTAGkey", jtagkey, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_oocdlinks_driver = { "OOCDLink-s", @@ -2711,7 +2711,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_oocdlinks_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xbaf8, "-mpsse", "OOCDLink-s", oocdlinks) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xbaf8, "-mpsse", "OOCDLink-s", oocdlinks, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_turtelizer2_driver = { "Turtelizer2", @@ -2731,7 +2731,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_turtelizer2_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xBDC8, "-mpsse", "Turtelizer2", turtelizer2) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xBDC8, "-mpsse", "Turtelizer2", turtelizer2, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_usbjtagrs232_driver = { "USB-JTAG-RS232", @@ -2751,7 +2751,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_usbjtagrs232_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x1457, 0x5118, "-mpsse", "USB-JTAG-RS232", usbjtagrs232) +URJ_DECLARE_FTDX_CABLE(0x1457, 0x5118, "-mpsse", "USB-JTAG-RS232", usbjtagrs232, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_usbtojtagif_driver = { "USB-to-JTAG-IF", @@ -2771,7 +2771,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_usbtojtagif_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0000, 0x0000, "-mpsse", "USB-to-JTAG-IF", usbtojtagif) +URJ_DECLARE_FTDX_CABLE(0x0000, 0x0000, "-mpsse", "USB-to-JTAG-IF", usbtojtagif, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_signalyzer_driver = { "Signalyzer", @@ -2791,7 +2791,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_signalyzer_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xbca1, "-mpsse", "Signalyzer", signalyzer) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xbca1, "-mpsse", "Signalyzer", signalyzer, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_flyswatter_driver = { "Flyswatter", @@ -2811,7 +2811,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_flyswatter_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "Flyswatter", flyswatter) +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "Flyswatter", flyswatter, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_usbscarab2_driver = { "usbScarab2", @@ -2831,7 +2831,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_usbscarab2_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xbbe0, "-mpsse", "usbScarab2", usbscarab2) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xbbe0, "-mpsse", "usbScarab2", usbscarab2, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_ktlink_driver = { "KT-LINK", @@ -2851,7 +2851,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_ktlink_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xbbe2, "-mpsse", "KT-LINK", ktlink) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xbbe2, "-mpsse", "KT-LINK", ktlink, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_milkymist_driver = { "milkymist", @@ -2871,7 +2871,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_milkymist_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x20b7, 0x0713, "-mpsse", "milkymist", milkymist) +URJ_DECLARE_FTDX_CABLE(0x20b7, 0x0713, "-mpsse", "milkymist", milkymist, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_digilenths1_driver = { "DigilentHS1", @@ -2891,7 +2891,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_digilenths1_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentHS1", digilenths1) +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentHS1", digilenths1, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_ft4232_driver = { "FT4232", @@ -2911,7 +2911,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_ft4232_driver = { ft2232_flush, ftdx_usbcable_extended_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6011, "-mpsse", "FT4232", ft4232) +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6011, "-mpsse", "FT4232", ft4232, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_jtagv3_driver = { "JTAGv3", @@ -2931,7 +2931,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_jtagv3_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xa6d0, "-mpsse", "JTAGv3", jtagv3) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xa6d0, "-mpsse", "JTAGv3", jtagv3, NULL) const urj_cable_driver_t urj_tap_cable_ft2232_jtagv5_driver = { "JTAGv5", @@ -2951,7 +2951,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_jtagv5_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xa6d0, "-mpsse", "JTAGv5", jtagv5) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xa6d0, "-mpsse", "JTAGv5", jtagv5, NULL) /* Local Variables: diff --git a/urjtag/src/tap/cable/generic_usbconn.h b/urjtag/src/tap/cable/generic_usbconn.h index 90af79b7..dada04bd 100644 --- a/urjtag/src/tap/cable/generic_usbconn.h +++ b/urjtag/src/tap/cable/generic_usbconn.h @@ -51,7 +51,7 @@ void urj_tap_cable_generic_usbconn_help_ex (urj_log_level_t ll, const char *cabl "INTERFACE Interface to use (0=first, 1=second, etc).\n" \ "INDEX Number of matching device (0=first, 1=second, etc).\n" -#define URJ_DECLARE_USBCONN_CABLE(vid, pid, driver, name, cable) \ -const urj_usbconn_cable_t urj_tap_cable_usbconn_##cable = { name, NULL, driver, vid, pid }; +#define URJ_DECLARE_USBCONN_CABLE(vid, pid, driver, name, cable, desc) \ +const urj_usbconn_cable_t urj_tap_cable_usbconn_##cable = { name, desc, driver, vid, pid }; #endif /* URJ_TAP_CABLE_GENERIC_H */ diff --git a/urjtag/src/tap/cable/ice100.c b/urjtag/src/tap/cable/ice100.c index 5a94d1d5..81603d10 100644 --- a/urjtag/src/tap/cable/ice100.c +++ b/urjtag/src/tap/cable/ice100.c @@ -1901,8 +1901,8 @@ const urj_cable_driver_t urj_tap_cable_ice100B_driver = { ice_cable_help, URJ_CABLE_QUIRK_ONESHOT }; -URJ_DECLARE_USBCONN_CABLE(0x064B, 0x1225, "libusb", "ICE-100B", ice100B) -URJ_DECLARE_USBCONN_CABLE(0x064B, 0x0225, "libusb", "ICE-100B", ice100Bw) +URJ_DECLARE_USBCONN_CABLE(0x064B, 0x1225, "libusb", "ICE-100B", ice100B, NULL) +URJ_DECLARE_USBCONN_CABLE(0x064B, 0x0225, "libusb", "ICE-100B", ice100Bw, NULL) /* Local Variables: diff --git a/urjtag/src/tap/cable/jlink.c b/urjtag/src/tap/cable/jlink.c index 8af32b70..e637ed91 100644 --- a/urjtag/src/tap/cable/jlink.c +++ b/urjtag/src/tap/cable/jlink.c @@ -720,4 +720,4 @@ const urj_cable_driver_t urj_tap_cable_jlink_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE(0x1366, 0x0101, "libusb", "jlink", jlink) +URJ_DECLARE_USBCONN_CABLE(0x1366, 0x0101, "libusb", "jlink", jlink, NULL) diff --git a/urjtag/src/tap/cable/usbblaster.c b/urjtag/src/tap/cable/usbblaster.c index 1e6f6bb0..bc686bf0 100644 --- a/urjtag/src/tap/cable/usbblaster.c +++ b/urjtag/src/tap/cable/usbblaster.c @@ -515,7 +515,7 @@ const urj_cable_driver_t urj_tap_cable_usbblaster_driver = { usbblaster_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6001, "", "UsbBlaster", usbblaster) -URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6002, "", "UsbBlaster", cubic_cyclonium) -URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6003, "", "UsbBlaster", nios_eval) -URJ_DECLARE_FTDX_CABLE(0x16C0, 0x06AD, "", "UsbBlaster", usb_jtag) +URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6001, "", "UsbBlaster", usbblaster, NULL) +URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6002, "", "UsbBlaster", cubic_cyclonium, NULL) +URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6003, "", "UsbBlaster", nios_eval, NULL) +URJ_DECLARE_FTDX_CABLE(0x16C0, 0x06AD, "", "UsbBlaster", usb_jtag, NULL) diff --git a/urjtag/src/tap/cable/vsllink.c b/urjtag/src/tap/cable/vsllink.c index 667229ac..91e2c9c4 100644 --- a/urjtag/src/tap/cable/vsllink.c +++ b/urjtag/src/tap/cable/vsllink.c @@ -575,4 +575,4 @@ const urj_cable_driver_t urj_tap_cable_vsllink_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE (0x0483, 0x5740, "libusb", "vsllink", vsllink) +URJ_DECLARE_USBCONN_CABLE (0x0483, 0x5740, "libusb", "vsllink", vsllink, NULL) diff --git a/urjtag/src/tap/cable/xpc.c b/urjtag/src/tap/cable/xpc.c index a46b0c4a..3d24cd10 100644 --- a/urjtag/src/tap/cable/xpc.c +++ b/urjtag/src/tap/cable/xpc.c @@ -704,7 +704,7 @@ const urj_cable_driver_t urj_tap_cable_xpc_int_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE(0x03FD, 0x0008, "libusb", "xpc_int", xpc_int) +URJ_DECLARE_USBCONN_CABLE(0x03FD, 0x0008, "libusb", "xpc_int", xpc_int, NULL) const urj_cable_driver_t urj_tap_cable_xpc_ext_driver = { "xpc_ext", @@ -724,4 +724,4 @@ const urj_cable_driver_t urj_tap_cable_xpc_ext_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE(0x03FD, 0x0008, "libusb", "xpc_ext", xpc_ext) +URJ_DECLARE_USBCONN_CABLE(0x03FD, 0x0008, "libusb", "xpc_ext", xpc_ext, NULL) diff --git a/urjtag/src/tap/usbconn/libftdx.h b/urjtag/src/tap/usbconn/libftdx.h index 70b14cb2..ae7bfae8 100644 --- a/urjtag/src/tap/usbconn/libftdx.h +++ b/urjtag/src/tap/usbconn/libftdx.h @@ -42,19 +42,19 @@ * Helpers to avoid having to copy & paste ifdef's everywhere */ #ifdef ENABLE_LOWLEVEL_FTDI -#define _URJ_DECLARE_FTDI_CABLE(v, p, d, n, c) URJ_DECLARE_USBCONN_CABLE(v, p, d, n, c) +#define _URJ_DECLARE_FTDI_CABLE(v, p, d, n, c, desc) URJ_DECLARE_USBCONN_CABLE(v, p, d, n, c, desc) #else -#define _URJ_DECLARE_FTDI_CABLE(v, p, d, n, c) +#define _URJ_DECLARE_FTDI_CABLE(v, p, d, n, c, desc) #endif #ifdef ENABLE_LOWLEVEL_FTD2XX -#define _URJ_DECLARE_FTD2XX_CABLE(v, p, d, n, c) URJ_DECLARE_USBCONN_CABLE(v, p, d, n, c) +#define _URJ_DECLARE_FTD2XX_CABLE(v, p, d, n, c, desc) URJ_DECLARE_USBCONN_CABLE(v, p, d, n, c, desc) #else -#define _URJ_DECLARE_FTD2XX_CABLE(v, p, d, n, c) +#define _URJ_DECLARE_FTD2XX_CABLE(v, p, d, n, c, desc) #endif -#define URJ_DECLARE_FTDX_CABLE(v, p, d, n, c) \ - _URJ_DECLARE_FTDI_CABLE(v, p, "ftdi"d, n, c##_ftdi) \ - _URJ_DECLARE_FTD2XX_CABLE(v, p, "ftd2xx"d, n, c##_ftd2xx) +#define URJ_DECLARE_FTDX_CABLE(v, p, d, n, c, desc) \ + _URJ_DECLARE_FTDI_CABLE(v, p, "ftdi"d, n, c##_ftdi, desc) \ + _URJ_DECLARE_FTD2XX_CABLE(v, p, "ftd2xx"d, n, c##_ftd2xx, desc) void ftdx_usbcable_help (urj_log_level_t ll, const char *cablename); void ftdx_usbcable_extended_help (urj_log_level_t ll, const char *cablename); -- 2.31.1 |
From: Anton B. <an...@oz...> - 2021-09-25 04:17:23
|
Some devices based on the FT2232 use the second interface, so add a way to set the interface field. --- urjtag/src/tap/cable/dirtyjtag.c | 2 +- urjtag/src/tap/cable/ft2232.c | 44 +++++++++++++------------- urjtag/src/tap/cable/generic_usbconn.h | 4 +-- urjtag/src/tap/cable/ice100.c | 4 +-- urjtag/src/tap/cable/jlink.c | 2 +- urjtag/src/tap/cable/usbblaster.c | 8 ++--- urjtag/src/tap/cable/vsllink.c | 2 +- urjtag/src/tap/cable/xpc.c | 4 +-- urjtag/src/tap/usbconn/libftdx.h | 14 ++++---- 9 files changed, 42 insertions(+), 42 deletions(-) diff --git a/urjtag/src/tap/cable/dirtyjtag.c b/urjtag/src/tap/cable/dirtyjtag.c index 94473e09..e8400935 100644 --- a/urjtag/src/tap/cable/dirtyjtag.c +++ b/urjtag/src/tap/cable/dirtyjtag.c @@ -338,4 +338,4 @@ const urj_cable_driver_t urj_tap_cable_dirtyjtag_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE(0x1209, 0xC0CA, "libusb", "dirtyjtag", dirtyjtag, NULL) +URJ_DECLARE_USBCONN_CABLE(0x1209, 0xC0CA, "libusb", "dirtyjtag", dirtyjtag, NULL, 0) diff --git a/urjtag/src/tap/cable/ft2232.c b/urjtag/src/tap/cable/ft2232.c index 3d029f39..2407ab9c 100644 --- a/urjtag/src/tap/cable/ft2232.c +++ b/urjtag/src/tap/cable/ft2232.c @@ -2589,7 +2589,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0000, 0x0000, "-mpsse", "FT2232", ft2232, NULL) +URJ_DECLARE_FTDX_CABLE(0x0000, 0x0000, "-mpsse", "FT2232", ft2232, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_armusbocd_driver = { "ARM-USB-OCD", @@ -2609,8 +2609,8 @@ const urj_cable_driver_t urj_tap_cable_ft2232_armusbocd_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0003, "-mpsse", "ARM-USB-OCD", armusbocd, NULL) -URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0004, "-mpsse", "ARM-USB-OCD", armusbocdtiny, NULL) +URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0003, "-mpsse", "ARM-USB-OCD", armusbocd, NULL, 0) +URJ_DECLARE_FTDX_CABLE(0x15BA, 0x0004, "-mpsse", "ARM-USB-OCD", armusbocdtiny, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_armusbtiny_h_driver = { "ARM-USB-OCD-H", @@ -2630,8 +2630,8 @@ const urj_cable_driver_t urj_tap_cable_ft2232_armusbtiny_h_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002A, "-mpsse", "ARM-USB-TINY-H", armusbtiny_h, NULL) -URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002B, "-mpsse", "ARM-USB-OCD-H", armusbocd_h, NULL) +URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002A, "-mpsse", "ARM-USB-TINY-H", armusbtiny_h, NULL, 0) +URJ_DECLARE_FTDX_CABLE(0x15BA, 0x002B, "-mpsse", "ARM-USB-OCD-H", armusbocd_h, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_gnice_driver = { "gnICE", @@ -2651,7 +2651,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_gnice_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0456, 0xF000, "-mpsse", "gnICE", gnice, NULL) +URJ_DECLARE_FTDX_CABLE(0x0456, 0xF000, "-mpsse", "gnICE", gnice, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_gniceplus_driver = { "gnICE+", @@ -2671,7 +2671,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_gniceplus_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0456, 0xF001, "-mpsse", "gnICE+", gniceplus, NULL) +URJ_DECLARE_FTDX_CABLE(0x0456, 0xF001, "-mpsse", "gnICE+", gniceplus, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_jtagkey_driver = { "JTAGkey", @@ -2691,7 +2691,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_jtagkey_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xCFF8, "-mpsse", "JTAGkey", jtagkey, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xCFF8, "-mpsse", "JTAGkey", jtagkey, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_oocdlinks_driver = { "OOCDLink-s", @@ -2711,7 +2711,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_oocdlinks_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xbaf8, "-mpsse", "OOCDLink-s", oocdlinks, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xbaf8, "-mpsse", "OOCDLink-s", oocdlinks, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_turtelizer2_driver = { "Turtelizer2", @@ -2731,7 +2731,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_turtelizer2_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xBDC8, "-mpsse", "Turtelizer2", turtelizer2, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xBDC8, "-mpsse", "Turtelizer2", turtelizer2, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_usbjtagrs232_driver = { "USB-JTAG-RS232", @@ -2751,7 +2751,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_usbjtagrs232_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x1457, 0x5118, "-mpsse", "USB-JTAG-RS232", usbjtagrs232, NULL) +URJ_DECLARE_FTDX_CABLE(0x1457, 0x5118, "-mpsse", "USB-JTAG-RS232", usbjtagrs232, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_usbtojtagif_driver = { "USB-to-JTAG-IF", @@ -2771,7 +2771,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_usbtojtagif_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0000, 0x0000, "-mpsse", "USB-to-JTAG-IF", usbtojtagif, NULL) +URJ_DECLARE_FTDX_CABLE(0x0000, 0x0000, "-mpsse", "USB-to-JTAG-IF", usbtojtagif, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_signalyzer_driver = { "Signalyzer", @@ -2791,7 +2791,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_signalyzer_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xbca1, "-mpsse", "Signalyzer", signalyzer, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xbca1, "-mpsse", "Signalyzer", signalyzer, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_flyswatter_driver = { "Flyswatter", @@ -2811,7 +2811,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_flyswatter_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "Flyswatter", flyswatter, "Flyswatter") +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "Flyswatter", flyswatter, "Flyswatter", 0) const urj_cable_driver_t urj_tap_cable_ft2232_usbscarab2_driver = { "usbScarab2", @@ -2831,7 +2831,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_usbscarab2_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xbbe0, "-mpsse", "usbScarab2", usbscarab2, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xbbe0, "-mpsse", "usbScarab2", usbscarab2, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_ktlink_driver = { "KT-LINK", @@ -2851,7 +2851,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_ktlink_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xbbe2, "-mpsse", "KT-LINK", ktlink, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xbbe2, "-mpsse", "KT-LINK", ktlink, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_milkymist_driver = { "milkymist", @@ -2871,7 +2871,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_milkymist_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x20b7, 0x0713, "-mpsse", "milkymist", milkymist, NULL) +URJ_DECLARE_FTDX_CABLE(0x20b7, 0x0713, "-mpsse", "milkymist", milkymist, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_digilenths1_driver = { "DigilentHS1", @@ -2891,7 +2891,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_digilenths1_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentHS1", digilenths1, "Digilent Adept USB Device") +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentHS1", digilenths1, "Digilent Adept USB Device", 0) const urj_cable_driver_t urj_tap_cable_ft2232_digilentnexysvideo_driver = { "DigilentNexysVideo", @@ -2911,7 +2911,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_digilentnexysvideo_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentNexysVideo", digilentnexysvideo, "Digilent USB Device") +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentNexysVideo", digilentnexysvideo, "Digilent USB Device", 0) const urj_cable_driver_t urj_tap_cable_ft2232_ft4232_driver = { "FT4232", @@ -2931,7 +2931,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_ft4232_driver = { ft2232_flush, ftdx_usbcable_extended_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6011, "-mpsse", "FT4232", ft4232, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6011, "-mpsse", "FT4232", ft4232, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_jtagv3_driver = { "JTAGv3", @@ -2951,7 +2951,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_jtagv3_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xa6d0, "-mpsse", "JTAGv3", jtagv3, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xa6d0, "-mpsse", "JTAGv3", jtagv3, NULL, 0) const urj_cable_driver_t urj_tap_cable_ft2232_jtagv5_driver = { "JTAGv5", @@ -2971,7 +2971,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_jtagv5_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0xa6d0, "-mpsse", "JTAGv5", jtagv5, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0xa6d0, "-mpsse", "JTAGv5", jtagv5, NULL, 0) /* Local Variables: diff --git a/urjtag/src/tap/cable/generic_usbconn.h b/urjtag/src/tap/cable/generic_usbconn.h index dada04bd..42f33213 100644 --- a/urjtag/src/tap/cable/generic_usbconn.h +++ b/urjtag/src/tap/cable/generic_usbconn.h @@ -51,7 +51,7 @@ void urj_tap_cable_generic_usbconn_help_ex (urj_log_level_t ll, const char *cabl "INTERFACE Interface to use (0=first, 1=second, etc).\n" \ "INDEX Number of matching device (0=first, 1=second, etc).\n" -#define URJ_DECLARE_USBCONN_CABLE(vid, pid, driver, name, cable, desc) \ -const urj_usbconn_cable_t urj_tap_cable_usbconn_##cable = { name, desc, driver, vid, pid }; +#define URJ_DECLARE_USBCONN_CABLE(vid, pid, driver, name, cable, desc, interface) \ +const urj_usbconn_cable_t urj_tap_cable_usbconn_##cable = { name, desc, driver, vid, pid, interface, 0 }; #endif /* URJ_TAP_CABLE_GENERIC_H */ diff --git a/urjtag/src/tap/cable/ice100.c b/urjtag/src/tap/cable/ice100.c index 81603d10..8e54b54c 100644 --- a/urjtag/src/tap/cable/ice100.c +++ b/urjtag/src/tap/cable/ice100.c @@ -1901,8 +1901,8 @@ const urj_cable_driver_t urj_tap_cable_ice100B_driver = { ice_cable_help, URJ_CABLE_QUIRK_ONESHOT }; -URJ_DECLARE_USBCONN_CABLE(0x064B, 0x1225, "libusb", "ICE-100B", ice100B, NULL) -URJ_DECLARE_USBCONN_CABLE(0x064B, 0x0225, "libusb", "ICE-100B", ice100Bw, NULL) +URJ_DECLARE_USBCONN_CABLE(0x064B, 0x1225, "libusb", "ICE-100B", ice100B, NULL, 0) +URJ_DECLARE_USBCONN_CABLE(0x064B, 0x0225, "libusb", "ICE-100B", ice100Bw, NULL, 0) /* Local Variables: diff --git a/urjtag/src/tap/cable/jlink.c b/urjtag/src/tap/cable/jlink.c index e637ed91..72c790bf 100644 --- a/urjtag/src/tap/cable/jlink.c +++ b/urjtag/src/tap/cable/jlink.c @@ -720,4 +720,4 @@ const urj_cable_driver_t urj_tap_cable_jlink_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE(0x1366, 0x0101, "libusb", "jlink", jlink, NULL) +URJ_DECLARE_USBCONN_CABLE(0x1366, 0x0101, "libusb", "jlink", jlink, NULL, 0) diff --git a/urjtag/src/tap/cable/usbblaster.c b/urjtag/src/tap/cable/usbblaster.c index bc686bf0..ce6f1452 100644 --- a/urjtag/src/tap/cable/usbblaster.c +++ b/urjtag/src/tap/cable/usbblaster.c @@ -515,7 +515,7 @@ const urj_cable_driver_t urj_tap_cable_usbblaster_driver = { usbblaster_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6001, "", "UsbBlaster", usbblaster, NULL) -URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6002, "", "UsbBlaster", cubic_cyclonium, NULL) -URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6003, "", "UsbBlaster", nios_eval, NULL) -URJ_DECLARE_FTDX_CABLE(0x16C0, 0x06AD, "", "UsbBlaster", usb_jtag, NULL) +URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6001, "", "UsbBlaster", usbblaster, NULL, 0) +URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6002, "", "UsbBlaster", cubic_cyclonium, NULL, 0) +URJ_DECLARE_FTDX_CABLE(0x09FB, 0x6003, "", "UsbBlaster", nios_eval, NULL, 0) +URJ_DECLARE_FTDX_CABLE(0x16C0, 0x06AD, "", "UsbBlaster", usb_jtag, NULL, 0) diff --git a/urjtag/src/tap/cable/vsllink.c b/urjtag/src/tap/cable/vsllink.c index 91e2c9c4..dee49ca2 100644 --- a/urjtag/src/tap/cable/vsllink.c +++ b/urjtag/src/tap/cable/vsllink.c @@ -575,4 +575,4 @@ const urj_cable_driver_t urj_tap_cable_vsllink_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE (0x0483, 0x5740, "libusb", "vsllink", vsllink, NULL) +URJ_DECLARE_USBCONN_CABLE (0x0483, 0x5740, "libusb", "vsllink", vsllink, NULL, 0) diff --git a/urjtag/src/tap/cable/xpc.c b/urjtag/src/tap/cable/xpc.c index 3d24cd10..6e7a8cfd 100644 --- a/urjtag/src/tap/cable/xpc.c +++ b/urjtag/src/tap/cable/xpc.c @@ -704,7 +704,7 @@ const urj_cable_driver_t urj_tap_cable_xpc_int_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE(0x03FD, 0x0008, "libusb", "xpc_int", xpc_int, NULL) +URJ_DECLARE_USBCONN_CABLE(0x03FD, 0x0008, "libusb", "xpc_int", xpc_int, NULL, 0) const urj_cable_driver_t urj_tap_cable_xpc_ext_driver = { "xpc_ext", @@ -724,4 +724,4 @@ const urj_cable_driver_t urj_tap_cable_xpc_ext_driver = { urj_tap_cable_generic_flush_using_transfer, urj_tap_cable_generic_usbconn_help }; -URJ_DECLARE_USBCONN_CABLE(0x03FD, 0x0008, "libusb", "xpc_ext", xpc_ext, NULL) +URJ_DECLARE_USBCONN_CABLE(0x03FD, 0x0008, "libusb", "xpc_ext", xpc_ext, NULL, 0) diff --git a/urjtag/src/tap/usbconn/libftdx.h b/urjtag/src/tap/usbconn/libftdx.h index ae7bfae8..56277e59 100644 --- a/urjtag/src/tap/usbconn/libftdx.h +++ b/urjtag/src/tap/usbconn/libftdx.h @@ -42,19 +42,19 @@ * Helpers to avoid having to copy & paste ifdef's everywhere */ #ifdef ENABLE_LOWLEVEL_FTDI -#define _URJ_DECLARE_FTDI_CABLE(v, p, d, n, c, desc) URJ_DECLARE_USBCONN_CABLE(v, p, d, n, c, desc) +#define _URJ_DECLARE_FTDI_CABLE(v, p, d, n, c, desc, interface) URJ_DECLARE_USBCONN_CABLE(v, p, d, n, c, desc, interface) #else -#define _URJ_DECLARE_FTDI_CABLE(v, p, d, n, c, desc) +#define _URJ_DECLARE_FTDI_CABLE(v, p, d, n, c, desc, interface) #endif #ifdef ENABLE_LOWLEVEL_FTD2XX -#define _URJ_DECLARE_FTD2XX_CABLE(v, p, d, n, c, desc) URJ_DECLARE_USBCONN_CABLE(v, p, d, n, c, desc) +#define _URJ_DECLARE_FTD2XX_CABLE(v, p, d, n, c, desc, interface) URJ_DECLARE_USBCONN_CABLE(v, p, d, n, c, desc, interface) #else -#define _URJ_DECLARE_FTD2XX_CABLE(v, p, d, n, c, desc) +#define _URJ_DECLARE_FTD2XX_CABLE(v, p, d, n, c, desc, interface) #endif -#define URJ_DECLARE_FTDX_CABLE(v, p, d, n, c, desc) \ - _URJ_DECLARE_FTDI_CABLE(v, p, "ftdi"d, n, c##_ftdi, desc) \ - _URJ_DECLARE_FTD2XX_CABLE(v, p, "ftd2xx"d, n, c##_ftd2xx, desc) +#define URJ_DECLARE_FTDX_CABLE(v, p, d, n, c, desc, interface) \ + _URJ_DECLARE_FTDI_CABLE(v, p, "ftdi"d, n, c##_ftdi, desc, interface) \ + _URJ_DECLARE_FTD2XX_CABLE(v, p, "ftd2xx"d, n, c##_ftd2xx, desc, interface) void ftdx_usbcable_help (urj_log_level_t ll, const char *cablename); void ftdx_usbcable_extended_help (urj_log_level_t ll, const char *cablename); -- 2.31.1 |
From: Anton B. <an...@oz...> - 2021-09-25 04:17:16
|
Flyswatter and Digilent use the same PID/VID, so we need to look at the description. Unfortunately Digilent use a different description for the Nexys Video, so we need to match against two strings. This means creating a copy of the urj_cable_driver_t data structure. --- urjtag/src/tap/cable/ft2232.c | 24 +++++++++++++++++++-- urjtag/src/tap/cable/generic_usbconn_list.h | 1 + urjtag/src/tap/cable_list.h | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/urjtag/src/tap/cable/ft2232.c b/urjtag/src/tap/cable/ft2232.c index 0540dbaa..3d029f39 100644 --- a/urjtag/src/tap/cable/ft2232.c +++ b/urjtag/src/tap/cable/ft2232.c @@ -2811,7 +2811,7 @@ const urj_cable_driver_t urj_tap_cable_ft2232_flyswatter_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "Flyswatter", flyswatter, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "Flyswatter", flyswatter, "Flyswatter") const urj_cable_driver_t urj_tap_cable_ft2232_usbscarab2_driver = { "usbScarab2", @@ -2891,7 +2891,27 @@ const urj_cable_driver_t urj_tap_cable_ft2232_digilenths1_driver = { ft2232_flush, ftdx_usbcable_help }; -URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentHS1", digilenths1, NULL) +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentHS1", digilenths1, "Digilent Adept USB Device") + +const urj_cable_driver_t urj_tap_cable_ft2232_digilentnexysvideo_driver = { + "DigilentNexysVideo", + N_("Digilent Nexys Video Adapter"), + URJ_CABLE_DEVICE_USB, + { .usb = ft2232_connect, }, + urj_tap_cable_generic_disconnect, + ft2232_cable_free, + ft2232_digilenths1_init, + ft2232_generic_done, + ft2232_set_frequency, + ft2232_clock, + ft2232_get_tdo, + ft2232_transfer, + ft2232_set_signal, + urj_tap_cable_generic_get_signal, + ft2232_flush, + ftdx_usbcable_help +}; +URJ_DECLARE_FTDX_CABLE(0x0403, 0x6010, "-mpsse", "DigilentNexysVideo", digilentnexysvideo, "Digilent USB Device") const urj_cable_driver_t urj_tap_cable_ft2232_ft4232_driver = { "FT4232", diff --git a/urjtag/src/tap/cable/generic_usbconn_list.h b/urjtag/src/tap/cable/generic_usbconn_list.h index 9c3cc9a8..82f5a453 100644 --- a/urjtag/src/tap/cable/generic_usbconn_list.h +++ b/urjtag/src/tap/cable/generic_usbconn_list.h @@ -64,6 +64,7 @@ _URJ_USB_FTDX(usbjtagrs232) _URJ_USB_FTDX(usbscarab2) _URJ_USB_FTDX(usbtojtagif) _URJ_USB_FTDX(digilenths1) +_URJ_USB_FTDX(digilentnexysvideo) _URJ_USB_FTDX(ft4232) #endif #ifdef ENABLE_CABLE_USBBLASTER diff --git a/urjtag/src/tap/cable_list.h b/urjtag/src/tap/cable_list.h index b321901c..d6a365af 100644 --- a/urjtag/src/tap/cable_list.h +++ b/urjtag/src/tap/cable_list.h @@ -64,6 +64,7 @@ _URJ_CABLE(ft2232_usbjtagrs232) _URJ_CABLE(ft2232_usbscarab2) _URJ_CABLE(ft2232_usbtojtagif) _URJ_CABLE(ft2232_digilenths1) +_URJ_CABLE(ft2232_digilentnexysvideo) _URJ_CABLE(ft2232_ft4232) #endif #ifdef ENABLE_CABLE_GPIO -- 2.31.1 |