mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	When small arguments (structures < 8 bytes or "float") are passed in a stack slot in the ppc64 SVR4 ABI, they must reside in the least significant part of that slot. On BE, this means that an offset needs to be added to the stack address of the parameter, but on LE, the least significant part of the slot has the same address as the slot itself. This changes the PowerPC back-end ABI code to only add the small argument stack slot offset for BE. It also adds test cases to verify the correct behavior on both BE and LE. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211368 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			60 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
; Verify that small structures and float arguments are passed in the
 | 
						|
; least significant part of a stack slot doubleword.
 | 
						|
 | 
						|
; RUN: llc < %s | FileCheck %s
 | 
						|
 | 
						|
target datalayout = "E-m:e-i64:64-n32:64"
 | 
						|
target triple = "powerpc64-unknown-linux-gnu"
 | 
						|
 | 
						|
%struct.large_arg = type { [8 x i64] }
 | 
						|
%struct.small_arg = type { i16, i8 }
 | 
						|
 | 
						|
@gl = common global %struct.large_arg zeroinitializer, align 8
 | 
						|
@gs = common global %struct.small_arg zeroinitializer, align 2
 | 
						|
@gf = common global float 0.000000e+00, align 4
 | 
						|
 | 
						|
define void @callee1(%struct.small_arg* noalias nocapture sret %agg.result, %struct.large_arg* byval nocapture readnone %pad, %struct.small_arg* byval nocapture readonly %x) {
 | 
						|
entry:
 | 
						|
  %0 = bitcast %struct.small_arg* %x to i32*
 | 
						|
  %1 = bitcast %struct.small_arg* %agg.result to i32*
 | 
						|
  %2 = load i32* %0, align 2
 | 
						|
  store i32 %2, i32* %1, align 2
 | 
						|
  ret void
 | 
						|
}
 | 
						|
; CHECK: @callee1
 | 
						|
; CHECK: lwz {{[0-9]+}}, 124(1)
 | 
						|
; CHECK: blr
 | 
						|
 | 
						|
define void @caller1() {
 | 
						|
entry:
 | 
						|
  %tmp = alloca %struct.small_arg, align 2
 | 
						|
  call void @test1(%struct.small_arg* sret %tmp, %struct.large_arg* byval @gl, %struct.small_arg* byval @gs)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
; CHECK: @caller1
 | 
						|
; CHECK: stw {{[0-9]+}}, 124(1)
 | 
						|
; CHECK: bl test1
 | 
						|
 | 
						|
declare void @test1(%struct.small_arg* sret, %struct.large_arg* byval, %struct.small_arg* byval)
 | 
						|
 | 
						|
define float @callee2(float %pad1, float %pad2, float %pad3, float %pad4, float %pad5, float %pad6, float %pad7, float %pad8, float %pad9, float %pad10, float %pad11, float %pad12, float %pad13, float %x) {
 | 
						|
entry:
 | 
						|
  ret float %x
 | 
						|
}
 | 
						|
; CHECK: @callee2
 | 
						|
; CHECK: lfs {{[0-9]+}}, 156(1)
 | 
						|
; CHECK: blr
 | 
						|
 | 
						|
define void @caller2() {
 | 
						|
entry:
 | 
						|
  %0 = load float* @gf, align 4
 | 
						|
  %call = tail call float @test2(float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float %0)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
; CHECK: @caller2
 | 
						|
; CHECK: stfs {{[0-9]+}}, 156(1)
 | 
						|
; CHECK: bl test2
 | 
						|
 | 
						|
declare float @test2(float, float, float, float, float, float, float, float, float, float, float, float, float, float)
 | 
						|
 |