Shop OBEX P1 Docs P2 Docs Learn Events
Strange problem with CALL indirect — Parallax Forums

Strange problem with CALL indirect

Peter JakackiPeter Jakacki Posts: 10,193
edited 2015-11-04 14:16 in Propeller 2
I have tracked down a problem with CALL REG where REG holds the address of a routine normally in the hub. Typically I will have task vectors that are normally zero for default but if I want them to do something different I load them up with the address of the routine I need it to be. But it just won't work and I checked the binary to make sure it was assembled correctly and it is. $FD63.302D where D is $198 so everything looks correct but it doesn't work. So I changed the setup so that it ended up doing a JMP REG instead and that works.

So this code is running in the hub but I will check its behaviour in cog as well and report back but this is mainly a heads-up for Chip to double check.
' Inline vector check and exeute - usage: QJMP,keypoll
'
QJMP		rdword	X,PTRA++	' read register address inline
		add	X,regptr	' add in task register offset
		rdword	X,X wz		' read contents of vector
	if_z	ret			' and ignore it if zero
		call	#EXIT
		jmp	X
{ this doesn't work		
		call	X		' execute vector
		jmp	#EXIT		' terminate rather than continue
}

Comments

  • I just wrote up a simple unit test for all 8 variations:

    * COG CALL # -> COG
    * COG CALL D -> COG
    * COG CALL # -> HUB
    * COG CALL D -> HUB
    * HUB CALL # -> HUB
    * HUB CALL D -> HUB
    * HUB CALL # -> COG
    * HUB CALL D -> COG

    All passed. I also tried the above tests with varying number of items in the stack, including a full stack.

    In your comments above, are you saying that the JMP works, as shown in the above code (i.e. preceded by a "call #EXIT")?

  • Seairth wrote: »
    I just wrote up a simple unit test for all 8 variations:

    * COG CALL # -> COG
    * COG CALL D -> COG
    * COG CALL # -> HUB
    * COG CALL D -> HUB
    * HUB CALL # -> HUB
    * HUB CALL D -> HUB
    * HUB CALL # -> COG
    * HUB CALL D -> COG

    All passed. I also tried the above tests with varying number of items in the stack, including a full stack.

    In your comments above, are you saying that the JMP works, as shown in the above code (i.e. preceded by a "call #EXIT")?

    Thanks for testing out all those variations and I know I must get down to the bottom of the problem and whether it might be a hardware stack problem as I haven't tried deliberately calling more than 8 levels deep. I don't think I'm that deep but I will have to check. Definitely though the code I used wouldn't work until I used the JMP and before then I even include some diagnostics to make sure it was executing the call instruction which it was but I don't know where it went to and it didn't crash either. The vector was correct and I could manually "call" it and the routine worked.
  • Huh. You'd think that the part that sets PC would be the same for both CALL and JMP.

    Incidentally, here's the test that I ran.

    https://github.com/Seairth/P2UnitTests/blob/master/test_call.spin

    When I tested the filled and partially-filled stack, I just inserted varying numbers of PUSH instructions at the top...
  • cgraceycgracey Posts: 14,152
    So, is there a problem?
  • jmgjmg Posts: 15,173
    Seairth wrote: »
    I just wrote up a simple unit test for all 8 variations:

    * COG CALL # -> COG
    * COG CALL D -> COG
    * COG CALL # -> HUB
    * COG CALL D -> HUB
    * HUB CALL # -> HUB
    * HUB CALL D -> HUB
    * HUB CALL # -> COG
    * HUB CALL D -> COG
    Isn't there also a LUT version of all these ?

  • jmg wrote: »
    Seairth wrote: »
    I just wrote up a simple unit test for all 8 variations:

    * COG CALL # -> COG
    * COG CALL D -> COG
    * COG CALL # -> HUB
    * COG CALL D -> HUB
    * HUB CALL # -> HUB
    * HUB CALL D -> HUB
    * HUB CALL # -> COG
    * HUB CALL D -> COG
    Isn't there also a LUT version of all these ?

    Oh yeah! I'll add them the next chance I get.
  • cgraceycgracey Posts: 14,152
    There are no LUT versions of CALL and RET.
  • cgracey wrote: »
    There are no LUT versions of CALL and RET.

    So you can't use CALL/RET to jump in and out of LUT exec mode?

  • cgraceycgracey Posts: 14,152
    Seairth wrote: »
    cgracey wrote: »
    There are no LUT versions of CALL and RET.

    So you can't use CALL/RET to jump in and out of LUT exec mode?

    You can!

    There just aren't any CALL/RET instructions that use the LUT as a stack.
  • cgracey wrote: »
    Seairth wrote: »
    cgracey wrote: »
    There are no LUT versions of CALL and RET.

    So you can't use CALL/RET to jump in and out of LUT exec mode?

    You can!

    There just aren't any CALL/RET instructions that use the LUT as a stack.

    Oh. Yeah, I wasn't expecting that anyhow. The tests just cover mode switches.
  • Okay. I added 10 more tests to the unit test mentioned above. It now tests both CALL D and CALL # from/to every combination of cog, hub, or lut (18 in all). I still did not encounter the OP issue.
  • cgraceycgracey Posts: 14,152
    Has this been resolved?
  • I will check this out again and get back to you. It was a real head scratcher.
Sign In or Register to comment.