Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EABI requires to pass structurs larger than 32 bits by reference #18

Closed
chbessonova opened this issue Oct 23, 2018 · 5 comments
Closed

Comments

@chbessonova
Copy link
Contributor

chbessonova commented Oct 23, 2018

p. 3.5 MSP430-EABI

Structures or Unions Passed and Returned by Reference
Structures (including classes) and unions larger than 32 bits are passed and returned by reference.
To pass a structure or union by reference, the caller places its address in the appropriate location: either in a register or on the stack, according to its position in the argument list...

Example:

struct t { long i; long j; };
void boo(struct t a1) {}

int test() {
  struct t a1 = { 1000, 10001 };
  boo(a1);
  return 0;
}

clang:

test:                                   ; @test
; %bb.0:
	push	r4
	mov	r1, r4
	sub	#16, r1
	mov	&.Ltest.a1+6, r12
	mov	r12, -2(r4)
	mov	&.Ltest.a1+4, r12
	mov	r12, -4(r4)
	mov	&.Ltest.a1+2, r12
	mov	r12, -6(r4)
	mov	&.Ltest.a1, r12
	mov	r12, -8(r4)
	mov	-2(r4), r12
	mov	r1, r13
	mov	r12, 6(r13)
	mov	-4(r4), r12
	mov	r12, 4(r13)
	mov	-6(r4), r12
	mov	r12, 2(r13)
	mov	-8(r4), r12
	mov	r12, 0(r13)
	call	#boo
	clr	r12
	add	#16, r1
	pop	r4
	ret

clang -02:

test:                                   ; @test
; %bb.0:
	push	r4
	mov	r1, r4
	sub	#8, r1
	mov	&.Ltest.a1+6, 6(r1)
	mov	&.Ltest.a1+4, 4(r1)
	mov	&.Ltest.a1+2, 2(r1)
	mov	&.Ltest.a1, 0(r1)
	call	#boo
	clr	r12
	add	#8, r1
	pop	r4
	ret

gcc:

test:
	SUB.W	#8, R1
	MOV.W	#1000, @R1
	MOV.W	#0, 2(R1)
	MOV.W	#10001, 4(R1)
	MOV.W	#0, 6(R1)
	MOV.W	R1, R12
	CALL	#boo
	MOV.B	#0, R12
	ADD.W	#8, R1
	RET
@mskvortsov
Copy link
Contributor

So in clang case we have a garbage in r12. This is incorrect.

@asl
Copy link
Contributor

asl commented Oct 23, 2018 via email

@chbessonova
Copy link
Contributor Author

For -O2 version:

target datalayout = "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"
target triple = "msp430"

%struct.t = type { i32, i32 }

@test.a1 = private unnamed_addr constant %struct.t { i32 1000, i32 10001 }, align 2

; Function Attrs: nounwind
define dso_local i16 @test() local_unnamed_addr #0 {
  tail call void @boo(%struct.t* byval nonnull align 2 @test.a1) #2
  ret i16 0
}

declare dso_local void @boo(%struct.t* byval align 2) local_unnamed_addr #1

@asl
Copy link
Contributor

asl commented Oct 23, 2018 via email

@chbessonova
Copy link
Contributor Author

Small note:
MSP430 EABI requires to pass/return structures larger than 32 bit by reference, but it says nothing specific about smaller structures (i.e. no requirements to pass/return them directly through registers/stack). Both TI GCC and TI compiler pass any structs (even smaller that 32 bit) by reference currently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants