Pass parameters from C to assembly for SH2

Ask anything your want about the 32X Mushroom programming.

Moderator: BigEvilCorporation

Post Reply
ammianus
Very interested
Posts: 124
Joined: Sun Jan 29, 2012 2:10 pm
Location: North America
Contact:

Pass parameters from C to assembly for SH2

Post by ammianus » Sat Feb 11, 2012 7:11 pm

I am trying build a function in assembly to be called from my C program that will be executed on the 32x.

I've seen some examples, but it is not clear to me how or if parameters get stored as registers or on the stack always?

Here is my function declaration in the .h file

Code: Select all

/*
* parameters:
*  x
*  y
*  xwidth
*  yheight
*  Framebuffer address
*
*/
extern void draw_rect(int, int, int, int, volatile unsigned short *);
If these are passed in to registers directly, the Hitachi docs for SH7604 don't really describe that, although this seems to happen for the example I've stepped through (3 arguments get passed to r4, r5, r6), is there logic to this I can follow?

If these are put on the stack as I've read from the web Mixing Assembly and C.

Is there any way I can debug or print out what I have from my assembly code? I have Gens, but there would be no way to break the execution to see what the stack has when my procedure is called?
Or would something like this work to get arguments from the stack?

Code: Select all

mov.l	@-r15,r0 ! store first param in r0
	mov.l	@-r15,r1 ! store second in r1	
	mov.l	@-r15,r2 ! r2 etc..
       ....
just guessing...

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sat Feb 11, 2012 7:59 pm

The ABI for SuperH is to pass the first four parameters in r4 to r7, and any others on the stack. Registers r8 to r14 and pr MUST be preserved if you use them... normally by pushing them on the stack, which is r15. r0 to r7 may be freely changed without saving, and the result is returned in r0 as long as it's 4 bytes or less. For 8 bytes or less, the result is returned in r0 and r1.

ammianus
Very interested
Posts: 124
Joined: Sun Jan 29, 2012 2:10 pm
Location: North America
Contact:

Post by ammianus » Sun Feb 12, 2012 12:20 am

Chilly Willy wrote:The ABI for SuperH is to pass the first four parameters in r4 to r7, and any others on the stack. Registers r8 to r14 and pr MUST be preserved if you use them... normally by pushing them on the stack, which is r15. r0 to r7 may be freely changed without saving, and the result is returned in r0 as long as it's 4 bytes or less. For 8 bytes or less, the result is returned in r0 and r1.
Thank you that helped to explain things for me. Got everything working now, in my case the first 4 int arguments are in r4-r7, the pointer to the framebuffer is in @r15 at the start of my procedure.


On a side note: Is there any known issues with Gens emulator (I have a Gens K-mod, and a Gens/GS) and SH instruction SHLR or SHAR? If I use either my game freezes. On Fusion 3.64 it works fine.

e.g.

Code: Select all

    SHLR r4 ! where r4 is value of 30

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sun Feb 12, 2012 1:05 am

ammianus wrote:Thank you that helped to explain things for me. Got everything working now, in my case the first 4 int arguments are in r4-r7, the pointer to the framebuffer is in @r15 at the start of my procedure.
No problem - I use assembly called from C in a number of my 32X stuff, so I hunted down the ABI info quite some time back.

On a side note: Is there any known issues with Gens emulator (I have a Gens K-mod, and a Gens/GS) and SH instruction SHLR or SHAR? If I use either my game freezes. On Fusion 3.64 it works fine.

e.g.

Code: Select all

    SHLR r4 ! where r4 is value of 30
Weird... there shouldn't be - I use Gens/GS r7 with a modification for proper DMA PWM. Can you give me an example of HOW you're using it? Maybe you're running into an odd alignment issue. Remember that words must be on a word boundary, and longs on a long boundary. Some emulators ignore that for better speed.

ammianus
Very interested
Posts: 124
Joined: Sun Jan 29, 2012 2:10 pm
Location: North America
Contact:

Post by ammianus » Sun Feb 12, 2012 12:33 pm

Chilly Willy wrote: Weird... there shouldn't be - I use Gens/GS r7 with a modification for proper DMA PWM. Can you give me an example of HOW you're using it? Maybe you're running into an odd alignment issue. Remember that words must be on a word boundary, and longs on a long boundary. Some emulators ignore that for better speed.
Originally I was doing basically this. I have multiplication, then store the results from MACL to r9. Then do my shift right 1 bit for r4 which didn't work

Code: Select all

loop: ! TODO start the loop
	muls.w r6, r7 ! width X height
	STS macl, r9 ! save size
	SHLR r4 ! divide x by 2 -- crashes GENS???, pass in already divided X
I've since found that it seems to work if I put another instruction between STS and SHLR e.g.

Code: Select all

loop: ! TODO start the loop
	muls.w r6, r7 ! width X height
	STS macl, r9 ! save size
	nop ! it first worked when I did a mov r4, r2 here, but nop works too
	SHLR r4 ! divide x by 2. Now it works?
So maybe you are right it is an alignment thing, but not sure i understand it.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sun Feb 12, 2012 4:57 pm

That's not enough to see what is causing the problem. I'd bet it's something else that only looks like the shift is the problem. One thing... you should stick another instruction between the mult and the sts macl - multiplies aren't ready on the next cycle. I'm not sure how Gens deals with that, but maybe it's part of the problem. In any case, you should stick at least one instruction in there for better speed on real hardware.

ammianus
Very interested
Posts: 124
Joined: Sun Jan 29, 2012 2:10 pm
Location: North America
Contact:

Post by ammianus » Sun Feb 12, 2012 7:56 pm

I see, I've added in instructions between the two and it is still working, so that's good. Once again your tips are helpful.

Post Reply