Pick three bugfixes from next branch to trunk for inclusion in 4.5.0 RC2, as discusse...
[sdcc.git] / sdcc / support / regression / tests / bug-3563.c
blob177b85eaf842de40c19f744f60ce746a68968c65
1 /* bug-3563.c
2 A parameter passing issue in the mcs51 port when using --stack-auto.
3 */
5 // According to bug reporter, his reproducing sample code, from which this regression test is derived, was derived from TinyUSb. TinyUSB is under MIT license.
7 #include <testfwk.h>
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include <string.h>
13 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
14 bool check_now;
16 void my_putchar(char c) {
17 (void)c;
20 void my_putchar_hex(uint8_t c) {
21 if (check_now)
22 ASSERT (!c);
25 void my_puts(char const * s) {
26 check_now = !strcmp (s, "rd_idx=");
29 typedef struct tu_fifo_t {
30 uint8_t* buffer ; // buffer pointer
31 uint16_t depth ; // max items
33 struct {
34 uint16_t item_size : 15; // size of each item
35 bool overwritable : 1 ; // ovwerwritable when full
38 volatile uint16_t wr_idx ; // write index
39 volatile uint16_t rd_idx ; // read index
40 } tu_fifo_t;
42 static inline
43 uint16_t idx2ptr(uint16_t depth, uint16_t idx)
45 // Only run at most 3 times since index is limit in the range of [0..2*depth)
46 while ( idx >= depth ) idx -= depth;
47 return idx;
50 static inline // WORKAROUND: comment out this line
51 void _ff_pull(tu_fifo_t* f, void * app_buf, uint16_t rel)
53 // WORKAROUND: move the puts("rel=") line here
55 memcpy(app_buf, f->buffer + (rel * f->item_size), f->item_size);
57 my_puts("rel="); my_putchar_hex(rel >> 8); my_putchar_hex(rel & 0xff); my_putchar('\n');
58 my_puts("app_buf="); my_putchar_hex((uintptr_t)app_buf >> 8); my_putchar_hex((uintptr_t)app_buf & 0xff); my_putchar('\n');
61 static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16_t rd_idx)
63 (void)wr_idx;
65 uint16_t rd_ptr = idx2ptr(f->depth, rd_idx); // becomes rel inside _ff_pull
67 // WORKAROUND: move rd_idx line here
69 // Peek data
70 _ff_pull(f, p_buffer, rd_ptr);
72 my_puts("rd_idx="); my_putchar_hex(rd_idx >> 8); my_putchar_hex(rd_idx & 0xff); my_putchar('\n');
73 my_puts("p_buffer="); my_putchar_hex((uintptr_t)p_buffer >> 8); my_putchar_hex((uintptr_t)p_buffer & 0xff); my_putchar('\n');
75 return true;
78 uint8_t app_buf[2];
80 int m(void) {
81 uint8_t buf[32];
83 tu_fifo_t fifo = {
84 .buffer = buf,
85 .depth = 16,
86 .item_size = 2,
87 .wr_idx = 1,
88 .rd_idx = 0
91 // Here we pass wr_idx = 1, rd_idx=0 but rd_idx will be reported as 0xe21d if you print
92 // it at any point after the memcpy inside _ff_pull. If you print it before that point,
93 // or if you remove the "inline" on _ff_pull, the correct value of 0 is printed.
95 _tu_fifo_peek(&fifo, app_buf, 1, 0);
97 return 0;
99 #endif
101 void
102 testBug (void)
104 #ifndef __SDCC_mcs51 // This bug #3563 is not yet fixed.
105 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
106 m ();
107 #endif
108 #endif