CPU_TC.048 TC1796 Need for NOP before RET?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User13921
Level 1
Level 1
Welcome! First question asked First reply posted
http://www.tasking.com/support/tricore/tc_user_guide_v3.0.pdf page 807 Tasking compiler/assembler manual says, "The assembler gives a warning when there is no or just one instruction (not a NOP instruction) between a label and a RET."

https://www.infineon.com/dgdl/TC1796_BC_Errata_Sheet_v2_2_02131A.pdf?fileId=db3a3043271faefd01273e57... TC1796 errata doesn't appear to mention this.
0 Likes
5 Replies
User13921
Level 1
Level 1
Welcome! First question asked First reply posted
tricore-as -mcpu048 does not insert a nop before the ret16 after "bill:" in this case when disassembling the output from Hightec:

.text:00000000 john:
.text:00000000 call16 bill
.text:00000002 ret16
.text:00000004
.text:00000004 ; =============== S U B R O U T I N E =======================================
.text:00000004
.text:00000004
.text:00000004 bill: ; CODE XREF: .text:johnp
.text:00000004 ret16
0 Likes
User13836
Level 6
Level 6
50 likes received 50 solutions authored 100 sign-ins
Hello!

As far as I understood you read the TASKING TriCore tools user guide but you are using the HighTec TriCore tools instead. Guess you need to look for the CPU_TC.048 problem bypass option for the HighTec tools.

For the TASKING tools the generated code for the example module:

void func_1(void)
{
}

when compiled using the CPU_TC.048 workaround option --silicon-bug=cpu-tc048 is:

.sdecl '.text.file_1.func_1',code
.sect '.text.file_1.func_1'
.align 2

.global func_1

; file_1.c 1 void func_1(void)
; Function func_1
func_1: .type func

; file_1.c 2 {
; file_1.c 3 }
nop ; added as a workaround for cpu_tc.048c
ret



Best regards,
Ulrich
0 Likes
User13921
Level 1
Level 1
Welcome! First question asked First reply posted
Thanks Ulrich. I invoked the option in Hightec and it did not insert the NOP. A TC1796 worked OK when I CALL into a RET16.
0 Likes
User13290
Level 5
Level 5
First like received First solution authored
Hi John,

jcsbanks wrote:
Thanks Ulrich. I invoked the option in Hightec and it did not insert the NOP. A TC1796 worked OK when I CALL into a RET16.


I tried the following sample case, to make sure to trigger the conditions for CPU.048:

extern void bar(void) __attribute__((longcall));

void foo(void)
{
bar();
}


Compiling it as follows, grepping for notices as I go:

[glas.AlbA] ➤ tricore-gcc -c -mcpu=tc1796 -Wa,-a foobar.c | grep -i notice
**** Notice:inserting NOP as a workaround for bug CPU_TC.048

Dumping the disassembly confirms that a NOP was indeed inserted:

[glas.AlbA] ➤ tricore-objdump.exe -d foobar.o | sed -n '/^.*[0-9,a-f]:/p'
0: 40 ae mov.aa %a14,%sp
2: 7b 00 00 f0 movh %d15,0
6: 1b 0f 00 f0 addi %d15,%d15,0
a: 60 ff mov.a %a15,%d15
c: 00 00 nop
e: 2d 0f 00 00 calli %a15
12: 00 90 ret

Note that the CALLI instruction (type LS) is preceded by a MOV.A (type IP) instruction. And since both make use of A15 a NOP must be inserted. Your own example makes use of a 24-bit displacement CALL (type LS) and I think that's the reason why a NOP is not required. It would have to've been an indirect call, making use of an address register that is used in an IP type instruction that precedes it. Neither condition is met so not inserting a NOP seems justified. Let me know if I'm overlooking something.

Best regards,

Henk-Piet Glas
Principal Technical Specialist
0 Likes
User13921
Level 1
Level 1
Welcome! First question asked First reply posted
Thanks Henk-Piet.

I think Tasking are being too cautious here and there is no need for a NOP "between a label and RET".

The NOP between (type IP) and (type LS) instruction is expected and consistent between Infineon manuals, Tasking and HIGHTEC.
0 Likes