Tool/software: TI C/C++ Compiler
Hello,
I probably have found a bug in TI PRU Code Generation Tools 2.3.3. It is leads in passing invalid values to function on implicit conversions.
Here is an example:
#include <stdint.h> #include <string.h> void memcpy16(void *dst, void *src, uint16_t size) { memcpy(dst, src, size); } void memcpy32(void *dst, void *src, uint32_t size) { memcpy(dst, src, size); } volatile void *src; volatile void *dst; volatile uint16_t size; void test(void) { memcpy16(src, dst, size); memcpy32(src, dst, size); } void main(void) { test(); }
Here, the memcpy() function call is enclosed in two almost identical functions memcpy16 and memcpy32. Functions differ only in the type of size argument.
- in call of memcpy32 size argument must be converted from uin16_t to uint32_t;
- in call of memcpy inside memcpy16 size argument must be converted from uint32_t to size_t.
I have compiled this program and get assembly listing with dispru.
TEXT Section .text (Little Endian), 0xd8 bytes at 0x0000001c 0x0000001c test: 0x0000001c main: 0000001c 050ee2e2 SUB R2, R2, 14 00000020 e100c2c3 SBBO &R3.b2, R2, 0, 14 00000024 240104e6 LDI R6, 260 00000028 240100e5 LDI R5, 256 0000002c 240108e4 LDI R4, 264 00000030 f100268e LBBO &R14.b0, R6, 0, 4 00000034 f100258f LBBO &R15.b0, R5, 0, 4 00000038 f1000490 LBBO &R16.b0, R4, 0, 2 0000003c 230025c3 JAL R3.w2, memcpy16 00000040 f1000480 LBBO &R0.b0, R4, 0, 2 00000044 f100268e LBBO &R14.b0, R6, 0, 4 00000048 f100258f LBBO &R15.b0, R5, 0, 4 0000004c 108080f0 AND R16, R0.w0, R0.w0 00000050 23002fc3 JAL R3.w2, memcpy32 00000054 f100c2c3 LBBO &R3.b2, R2, 0, 14 00000058 010ee2e2 ADD R2, R2, 14 0000005c 20c30000 JMP R3.w2 0x00000060 memcpy: 00000060 5100f00c QBEQ return, R16, 0 00000064 10eeeef1 AND R17, R14, R14 0x00000068 start: 00000068 24003000 LDI R0.b0, 48 0000006c 70f00002 QBGE copy, R0.b0, R16 00000070 10f0f000 AND R0.b0, R16, R16 0x00000074 copy: 00000074 0400f0f0 SUB R16, R16, R0.b0 00000078 ff00cf12 LBBO &R18.b0, R15, 0, 125 0000007c ef00d112 SBBO &R18.b0, R17, 0, 125 00000080 5100f004 QBEQ return, R16, 0 00000084 0000efef ADD R15, R15, R0.b0 00000088 0000f1f1 ADD R17, R17, R0.b0 0000008c 21001a00 JMP start 0x00000090 return: 00000090 20c30000 JMP R3.w2 0x00000094 memcpy16: 00000094 0502e2e2 SUB R2, R2, 2 00000098 e10002c3 SBBO &R3.b2, R2, 0, 2 0000009c 10000000 AND R0.b0, R0.b0, R0.b0 000000a0 10000000 AND R0.b0, R0.b0, R0.b0 000000a4 10000000 AND R0.b0, R0.b0, R0.b0 000000a8 10000000 AND R0.b0, R0.b0, R0.b0 000000ac 230018c3 JAL R3.w2, memcpy 000000b0 f10002c3 LBBO &R3.b2, R2, 0, 2 000000b4 0102e2e2 ADD R2, R2, 2 000000b8 20c30000 JMP R3.w2 0x000000bc memcpy32: 000000bc 0502e2e2 SUB R2, R2, 2 000000c0 e10002c3 SBBO &R3.b2, R2, 0, 2 000000c4 10000000 AND R0.b0, R0.b0, R0.b0 000000c8 10000000 AND R0.b0, R0.b0, R0.b0 000000cc 10000000 AND R0.b0, R0.b0, R0.b0 000000d0 10000000 AND R0.b0, R0.b0, R0.b0 000000d4 230018c3 JAL R3.w2, memcpy 000000d8 f10002c3 LBBO &R3.b2, R2, 0, 2 000000dc 0102e2e2 ADD R2, R2, 2 000000e0 20c30000 JMP R3.w2 0x000000e4 abort: 000000e4 23003bc3 JAL R3.w2, C$$EXIT 0x000000e8 $C$L1: 000000e8 21003a00 JMP $C$L1 0x000000ec C$$EXIT: 0x000000ec loader_exit: 000000ec 10000000 AND R0.b0, R0.b0, R0.b0 000000f0 20c30000 JMP R3.w2
Second conversion is not found:
- offset 00000038: size is placed in first two bytes of R16;
- offset 0000003c: call memcpy16;
- offset 000000ac: memcpy16 does nothing with R16 and just call memcpy;
- offset 00000060: memcpy use R16 as 32-bit value.
Is it right place to post such reports?